🐕

JavaScriptに入門してみる(独学)

2024/02/25に公開

はじめに

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