JavaScriptに入門してみる(独学)
はじめに
C言語やC#など静的型付け言語の住人ですが、JavaScriptを勉強しています。
まったくの独学なので、基本的なところを復習中ですが、その中でちょっと疑問に思った点とかをメモです。
配列
宣言
初期値を代入しない配列の生成には、コンストラクタとリテラルの2つの方法があるそうです。
const a = Array(); //コンストラクタ
const b = []; //リテラル
console.log(a); // []
console.log(typeof(a)); // object
console.log(b); // []
console.log(typeof(b)); // object
どちらの方法でも結果は同じです。
ちなみにコンストラクタでnewを付けて記述の場合もあります。
const a1 = Array();
const a2 = new Array();
console.log(a1); // []
console.log(typeof(a1)); // object
console.log(a2); // []
console.log(typeof(a2)); // object
こちらも結果は同じでした。どうやらArrayオブジェクトに関しては動作が同じの様です。
たとえばStringオブジェクトなどでは、違っているみたいです。
const a1 = String();
const a2 = new String();
console.log(a1); //
console.log(typeof(a1)); // string
console.log(a2); // [ STring:'']
console.log(typeof(a2)); // object
初期値
次に初期値を設定する場合には、
console.log( Array(1,2,3) ); //1,2,3
console.log( [1,2,3] ); //1,2,3
これはすんなり理解できますね。
ただし、整数を1個だけにすると、動きが違ってきます。
console.log( Array(3) ); //[ <3 empty items> ]
console.log( [3] ); //3
コンストラクタの場合には、3個の中身の無い配列を作成するけど、リテラルの場合には、3という値が入った1個の配列を作成すると。もうちょっと詳しく書くと、
const a = [10];
console.log(a[0]); // 10
console.log(a.length); // 1
console.log(a[1]); // undefined
では、次に初期値を設定せずに配列を宣言して、あとで初期値を代入したい場合を想定しましょう。これはforループで1個ずつ代入していけばいいですね
const a = Array()
for (let i = 0; i < 3; ++i)
a.push(i)
console.log(a) //[ 0, 1, 2 ]
なんか良くないですね、そこでmap関数で代入していけばいいんじゃね?
console.log(Array(3).map((v,i)=>i)); //[ <3 empty items> ]
思い通りには行きません。ここはfromを使用するらしいです。
console.log(Array.from(Array(3)).map((v, i) => i)); //[ 0, 1, 2 ]
この「Array.from」とはなんだ?ですよね。
Array.fromとは、配列の中身を「undefined」で埋める動作を行うらしいです。要するに、
console.log(Array(10));
console.log(Array.from(Array(10)));
これの出力が
[ <10 empty items> ]
[
undefined, undefined,
undefined, undefined,
undefined, undefined,
undefined, undefined,
undefined, undefined
]
となります。Array(10)だけの場合では、長さを決めただけで要素が空になっているので、forEachやmapなどが一回も処理されないのですが、Array.fromを付加すると、中身をundefinedで埋めるので、foreachやmapが正しく処理されると。
スプレッド構文
スプレッド構文という方法でも、同様の事が出来ます。スプレッド構文とは、...の記法です。配列をその場に展開する感じです。
const a = [...Array(3)].map((_, h) => h);
分解して考えると
console.log(Array(3)) //[ <3 empty items> ]
console.log([...Array(3)]) //[ undefined, undefined, undefined ]
スプレッド構文によって、未定義が3個ある配列になり、その後のmapが使用出来る様になったという事ですね。
Discussion