tc39_study: Record & Tuple
注意事項
- これは#tc39_studyの発表資料です
- この機能はまだ提案/策定途中であり仕様に入るまでに大きな変更が入る可能性があり、またこの機能の策定自体が中止される可能性もあります。
ステータス
- proposal
- Champion
- Robin Ricard (Bloomberg)
- Richard Button (Bloomberg)
- Stage: 1 (0 to 1 per 2019.10.01 TC39)
- (Stage0 の時点では “Const Value Types: Record & Tuple” 名前だった)
- 実装済みのエンジン: なし
モチベーション
言語レベルで immutable なデータ型が欲しい
これまでと現状
- かつて別の提案があったが、仕様の複雑さとユースケースの観点から廃棄された
- Immutable.js などのライブラリが存在する
Record
基本の Syntax
const record1 = #{
a: 1,
b: 2,
c: 3,
};
record1.a === 1; // true
record1["a"] === 1; //true
スプレッド構文
const record2 = #{ ...record1, b: 5 };
record1 !== record2; //true
record2 === #{ a: 1, c: 3, b: 5 }; // true
Iteration
const record = #{ a: 1, b: 2 };
// TypeError: record is not iterable
for (const o of record) {
console.log(o);
}
Record は iterable ではない
Tuple
基本の Syntax
const tuple1 = #[1, 2, 3];
tuple1[0] === 1; // true
with
const tuple2 = tuple1.with(0, 2);
tuple1 !== tuple2; // true
tuple2 === #[2, 2, 3]; // true
スプレッド構文
const tuple3 = #[1, ...tuple2];
tuple3 === #[1, 2, 2, 3]; // true
push
, pop
const tuple4 = tuple3.push(4);
tuple4 === #[1, 2, 2, 3, 4]; // true
const tuple5 = tuple4.pop();
tuple5 === #[2, 2, 3, 4]; // true
Iteration
// 1
// 2
for (const o of tuple) {
console.log(o);
}
Equality
-0
のケースは常にfalse
、NaN
のケースは常にtrue
(?)- 議論の issue
-0 === +0; // true
Object.is(-0, +0); //false
#{ a: -0 } === #{ a: +0 }; //false
#[-0] === #[+0]; //false
NaN === NaN; // false
Object.is(NaN, NaN); // true
#{ a: NaN } === #{ a: NaN }; // true
#[NaN] === #[NaN]; // true
JSON.stringify
JSON.stringify(record)
はJSON.stringify(object)
と同じ結果JSON.stringify(tuple)
はJSON.stringify(array)
と同じ結果
JSON.stringify(#{ a: #[1, 2, 3] }); // '{"a":[1,2,3]}'
JSON.stringify(#[true, #{ a: #[1, 2, 3] }]); // '[true,{"a":[1,2,3]}]'
typeof
現在のところどちらもrecord
になるのが妥当だと考えられている
typeof { a: 1 } === "object";
typeof [1, 2] === "object";
typeof #{ a: 1 } === "record";
typeof #[1, 2] === "record";