Twitter hashtag: #esspec
YouTube: https://youtu.be/gew7MMjku4w
自己紹介 (近況報告)
syumai
GoとTSやってます
先々週末Go Con mini Sendaiと言うイベントで仙台に行きます
Jun Yasumura / harupiyo Jun Yasumura.icon
tars0x9752 (たーず / naoki aoyama) tars0x9752.icon
噂の trpc でハローワールド
ついでにちょっとしたコントリビュートした
rspc でもハローワールド
rust 版の trpc 的なやつ
サーバーは Rust
クライアントは TS
rust なにもわからん
yebis0942yebis0942.icon
TypeScript入門しつつあります
Array.prototype.filterで値の型を絞り込めたと思ったら絞り込めてないとか
code:ts
array.filter(i => i.type === "hoge") // i.type === "hoge"の型だけ絞り込めると思ったら絞り込めてない
マイクの接触が怪しいかも
前回のあらすじ
code:js
a'-0' // expected: 1, actual: undefined Integer-Indexed Exotic Objects は Typed Array についての仕様だった
code:js
const ua = new Uint8Array(2); // Typed Array
こちらは期待通りの挙動をしている
Testing and Comparison Operations
RequireObjectCoercible: ToObjectできるかどうか判定するやつ
IsArray, IsCallable, IsConstructor, IsExtensible, IsIntegralNumber, IsPropertyKey などなど
IsRegExp
今日の範囲
IsStringWellFormedUnicode
文字列をUTF-16のコードポイントシーケンスとして解釈して、well formed なUTF-16シーケンスになってるか判定する
well formed?
Well-formed: A Unicode code unit sequence that purports to be in a Unicode encoding form is called well-formed if and only if it does follow the specification of that Unicode encoding form
Unicode 仕様にしたがっていれば well formed っぽい?
たぶん String Value
生成規則中の文字列を String Value にする static semantics
どこで使われているのか
具体的にどういうコードだとそうなるのか
サロゲートペア
𩸽 とか
not well formed?
0xD800-0xDFFF は pairs の中でしか登場してはいけないらしい?
こういうやつかもyebis0942.icon
code:a.mjs
import { "\uD800" as a } from "lib" // unicode sequenceで不正なModuleExportNameを作る
code:result
$ node a.mjs
file:///tmp/a/a.mjs:3
import { "\uD800" as a } from "lib"
^^^^^^^^
SyntaxError: Invalid module export name: contains unpaired surrogate
SameValue
If Type(x) is different from Type(y)
ECMAScript language valueの型の同一性はどのように定義されているのか?
yebis0942.icon定義見つからず。nominal type的に同一性を見ているのだろうか。
IsStrictlyEqualとの違い: NaN, +0, -0の扱いが違う
SameValue: NaN == NaN, +0 == -0 (Number::sameValue)
IsStrictlyEqual: NaN != NaN, +0 != -0 (Number::equal)
試してみる
code:js
NaN == NaN // false
Object.is(NaN, NaN) // true (Object.isはSameValueを即呼んでいる)
IsLooselyEqualも型が同じならIsStrictlyEqualを呼んでいる
SameValue はどこで使われているか
めちゃめちゃ使われている
Object.is など
Object.isは引数をオブジェクトに変換しない(Objectのメソッドなのに)
SameValueZero
SameValueと同じ。ただし+0𝔽と-0𝔽を同一視する。
どこで使われているのか
Set, Mapのキーの比較
配列の長さ的なものの比較
実験してみる
code:js
s = new Set
s.add(-0); s.add(0) // -0と0は同一視される
s.size // 1
code:js
m = new Map()
m.set(0, "a"); m.set(-0, "b") // -0と0は同一視される
m.get(0) // b
SameValueNonNumber
すでに見たので略
IsLessThan
引数: x, y, LeftFirst (boolean)
返り値は以下のいずれか
normal completion record<Boolean | undefined>
throw completion
LeftFirst
xとyのどちらを先に評価するか
ToPrimitiveに副作用があるのでどっちを優先するか決める必要があるっぽい
getterを使えばxやyの値を参照した時点で副作用発生させることも可能そうyebis0942.icon
yebis0942.iconLeftFirstが指定されずに呼ばれてるケースありそう
Math.max, Math.min
追記:x < y だけじゃなくて x > y みたいなコードに対しても isLessThan が使われてるっぽくてそのときに leftFirst が指定されたりしてた
code:js
// <と>のどちらでも評価順が適切になっていることを確認する
{
const o = {};
Object.defineProperty(o, key, {
get: () => {
console.log(evaluated: ${key});
return 0;
}
})
}
o.a < o.b; // evaluated: a, evaluated: b
o.b > o.a; // evaluated: b, evaluated: a (LeftFirstがなければ a -> bの順で評価されてしまう)
}
string 同士の場合は辞書順で比較っぽい
どっちも同じ文字列なら false
code:js
"abc" < "abcd"
// true
"abc" < "abc"
// false
"abc" < "abb"
// false
"abc" < "abd"
// true
Code pointとCode unitの違い
参考:
言語によって文字の順序が違う例
スウェーデン語では z < ö
ドイツ語では ö < z
tars0x9752.iconなるほど~
isLessThan は Unicode 仕様書とは異なる(Unicode 仕様書はもっと複雑)
BigInt と String
String を BigInt に変換して比較
なお, String から BigInt への変換を失敗したら undefined
code:js
100000000000000000n <
"100000000000000001"
// true
"100000000000000000" <
100000000000000001n
// true
Number 同士
Number:lessThan
(無限大同士の比較もここ)
BigInt 同士
BigInt:lessThan
どちらかが NaN
undefined
BigInt と Number
Mathematical Value として比較
code:js
({}).toString()
// false
// true
({}) < '[object Object'
// false
undefined < undefined // NaN
// false
undefined < 1
// false
undefined < -1
// false
undefined < "abc"
// false
undefined < Infinity
// false
null < 1
// true
null < -1
// false
null < null
// false
null < true
// true
null < "1"
// true
null < "-1"
// false
Number("")
// 0
null < ""
// false
const s = Symbol("a")
// undefined
s < "b"
// VM2539:1 Uncaught TypeError
function A() {}
// undefined
new A
// A {}
A.prototype.toString = () => "42";
// () => "42"
const a = new A();
// undefined
a.toString();
// '42'
a < 43
// true
a < 41
// false
code:js
"0101" < "100"
// true
"0101" < 100
// false
"0101" + "100"
// '0101100'
"0101" + 100
// '0101100'
lexicographical order
辞書式順序
canonically
標準的に
余談コーナー
IsLessThanはメソッド分割してほしかったyebis0942.icon
toString()は文字列以外を返してもOKなのか?
code:js
o = ({ toString() { return 42 } })
o < 50 // true
OKっぽい…
次回: IsLooselyEqual から