画像遅延読み込みについて調べていると、
let images = [].slice.call(document.querySelectorAll('.lazyload'));
のような、「[].slice.call() 」という構文がでてきたので、調べてみた。
MDNの解説では、
========================
”slice メソッドを呼び出すことで、配列風オブジェクトやコレクションを新しい配列に変換することができます。
メソッドをオブジェクトに繋げるだけです。配列風オブジェクトの一例として、 arguments が挙げられます。以下に例を示します。”
========================
引用:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
function list() { return Array.prototype.slice.call(arguments); } var list1 = list(1, 2, 3); // [1, 2, 3]
この「Array.prototype.slice」を短縮する書き方が「[ ].slice」です。
ここで、配列風オブジェクトとは何か?
まず、javascripでは、数値、文字列、真偽値、null、undefined 以外の全てはオブジェクトであり、配列もオブジェクトです。その中で配列は、一般的なオブジェクトより高機能なオブジェクトなだけです。また、このオブジェクトはプロパティを持つことができます。
配列風オブジェクトとは、配列のよう要素的なものを持ち、lengthも持っているが、配列のような slice や sort などの配列特有のメゾットを持たないオブジェクトです。また、forEach などの配列の各要素を順に処理していくメゾットも利用できません。
ここで、具体的な例をあげてみます。
var object = { name: 'plusone', age: 22 }, //配列風オブジェクト array = [1, 2, 3]; //配列 console.log(object['name']);// output 'plusone' console.log(array[1]); // output 2
今回実際に、使用した querySelectorAll() の戻り値は、Nodelist になり、まさに上記で説明した「配列風オブジェクト」になります。
そのため、querySelectorAll() で取り出した要素に順に処理を与えようと forEach をそのまま使用してもエラーになります。
そこで、冒頭に出した「[].slice.call() 」で、「配列風オブジェクト」(Nodelist) を配列に変換してあげるわけです。
let images = [].slice.call(document.querySelectorAll('.lazyload'));
なお、ES2015では、「配列風オブジェクト」(Nodelist) を配列に変換するのには、以下の構文も使用できます。
// Array.from() var args = Array.from(arguments); // スプレッド構文 var args = [...arguments];