「JavaScript 第7版」を読む(6章~7章:オブジェクトと配列)
前回のスクラップの続き
プロトタイプを使ったオブジェクトの生成
const obj = Object.create({x: "Hello"});
console.log(obj); // {}
console.log(obj.x); // Hello
console.log("x" in obj); // true
console.log(obj.hasOwnProperty("x")); // false
// 以下の2行は同じ
const obj = Object.create(Object.prototype);
const obj = {};
オブジェクトのキーの識別には文字列か数字かの区別がないのか。
const obj = {
"0": "Hello",
}
console.log(obj); // { '0': 'Hello' }
console.log(obj[0]); // Hello
console.log(obj["0"]); // Hello
const obj = {
0: "Hello",
}
console.log(obj); // { '0': 'Hello' }
console.log(obj[0]); // Hello
console.log(obj["0"]); // Hello
const obj = {}
obj[0] = "Hello";
console.log(obj); // { '0': 'Hello' }
console.log(obj[0]); // Hello
console.log(obj["0"]); // Hello
プロパティの列挙順序は、以下の3グループの順に、それぞれソートされる。
- 0以上の整数(の文字列)
- 小さい数字から順に
- それ以外の文字列(負や小数点付きの数字のような文字列も含む)
- オブジェクトに追加された順に
- Symbol
- オブジェクトに追加された順に
ただし、for/in
ループでの列挙順序は厳密な仕様がない。とはいえ、ほとんどの処理系ではこの列挙順序に従っている。
Object.assign
は列挙可能なプロパティを上書きコピーする。
const obj1 = {
x: 1,
y: 2,
}
const obj2 = {
y: 20,
z: 30,
}
console.log(Object.assign({w: "Hello", x: "World"}, obj1, obj2));
// { w: 'Hello', x: 1, y: 20, z: 30 }
console.log({...{w: "Hello", x: "World"}, ...obj1, ...obj2});
// { w: 'Hello', x: 1, y: 20, z: 30 }
valueOf
メソッドは数値型に変換するメソッド。toString
が文字列への変換であることに対応する。比較演算子で比較する際に呼び出される。
こんな書き方ができる。
const keyName = "a";
const obj = {
[keyName]: 1,
}
console.log(obj); // { a: 1 }
[]
の中には変数名だけでなく、任意の式が書ける。
アクセッサ(ゲッターとセッター)
const obj = {
propField: 1,
get prop() {
return this.propField;
},
set prop(value) {
this.propField = value;
},
}
console.log(obj.prop); // 1
console.log(Object.keys(obj)); // [ 'propField', 'prop' ]
JavaScriptのいわゆる配列はオブジェクトの特別の形式。
ES6で「型付き配列」が導入されたが。型付き配列は固定長なのに対して、いわゆる配列は可変長であり、疎な配列も可能。
疎な配列
// 疎な配列
const arr = [1, , 2, ];
console.log(arr); // [ 1, <1 empty item>, 2 ]
console.log(arr.length); // 3
// 疎な配列
const arr = [1, , 2, , ];
console.log(arr); // [ 1, <1 empty item>, 2, <1 empty item> ]
console.log(arr.length); // 4
Set
を使うと重複を削除できる。
文字列も反復可能なので、次のように書ける。
console.log([...new Set("Hello World")]); // [ 'H', 'e', 'l', 'o', ' ', 'W', 'r', 'd' ]
Array.from
は配列のような見た目のオブジェクトから本当の配列を作れる。
console.log(Array.from({
length: 3,
0: 'a',
2: 'c',
}));
// [ 'a', undefined, 'c' ]
非負の整数のインデックスで要素を更新すればlength
も必要に応じて更新される。非負の整数であれば文字列でも許容される。
const arr = [1, 2, 3, 4, 5];
console.log(arr.length); // 5
arr[10] = "Hello";
console.log(arr); // [ 1, 2, 3, 4, 5, <5 empty items>, 'Hello' ]
console.log(arr.length); // 11
arr["11"] = "World";
console.log(arr); // [ 1, 2, 3, 4, 5, <5 empty items>, 'Hello', 'World' ]
console.log(arr.length); // 12
arr["-1"] = "minus";
console.log(arr); // [ 1, 2, 3, 4, 5, <5 empty items>, 'Hello', 'World', '-1': 'minus' ]
console.log(arr.length); // 12 のまま変わらない
配列の高階関数のメソッド
Scalaに翻訳すると私にはわかりやすいので、表で対応をまとめる。
JavaScript | Scalaで対応するもの |
---|---|
forEach |
foreach |
map |
map |
filter |
filter |
find |
find |
findIndex |
indexWhere |
every |
forall |
some |
exists |
reduce |
reduceLeft , foldLeft
|
reduceRight |
reduceRight , foldRight
|
sort |
sorted , sortWith
|
flat |
flatten |
flatMap |
flatMap |
indexOf |
indexOf |
lastIndexOf |
lastIndexOf |
reduce
は関数だけを引数として渡せば、ScalaのreduceLeft
相当になる。2つ目の引数として初期値を渡せば、ScalaのfoldLeft
相当になる。recudeRight
も同様。
JavaScriptのsort
関数はScalaと違い配列自体を書き換える。引数を渡さなければデフォルトのソート順、関数を引数として渡せばその関数を使ってソートされる。引数の関数のシグニチャはScalaとは異なる。
indexOf
, lastIndexOf
は要素の比較の際には ==
ではなく ===
が使われる。
※表の最後のほうは高階関数ではない
に追加 | を取得して削除 | |
---|---|---|
先頭 | unshift |
shift |
最後 | push |
pop |
push
とunshift
は複数を同時に追加することができる。
const arr = [1, 2, 3];
arr.push("Hello", "World");
console.log(arr); // [ 1, 2, 3, 'Hello', 'World' ]
const arr = [1, 2, 3];
const arr2 = ["Hello", "World"];
arr.push(...arr2);
console.log(arr); // [ 1, 2, 3, 'Hello', 'World' ]
unshift
は直観と順番が逆かもしれない。
const arr = [1, 2, 3];
arr.unshift("Hello", "World");
console.log(arr); // [ 'Hello', 'World', 1, 2, 3 ]
arr.slice(start, end)
文字列はUTF-16コードの配列のようにふるまう。ただしイミュータブル。
ソートに関して
const arr = [3, 2, 5, 1, 4];
arr.sort();
console.log(arr); // [1, 2, 3, 4, 5]
const arr = [3, 2, 5, 1, 4];
arr.sort((a, b) => b - a);
console.log(arr); // [ 5, 4, 3, 2, 1 ]