[].slice.call()とは
2020/08/22
どうやら配列風オブジェクトを配列に変換する記法らしい。
//配列風オブジェクト
const elms = document.querySelectorAll('.elm');
//配列に変換
const elmArr = [].slice.call(elms);
//配列なのでsliceメソッドを使える
elmArr.slice();
解説
🐳 NodeList
Document.querySelectorAll()
メソッドは、配列風オブジェクトであるNodeList
を取得する。
NodeListはArrayオブジェクトを継承していないので、slice
やpush
などのArray.prototype
が持つメソッドを使用できない。
//配列風オブジェクト
const elms = document.querySelectorAll('.elm');
//配列ではないのでsliceメソッドを使えない
elms.slice(); // エラーが起こる
そのため、配列風オブジェクトでArray.prototypeメソッドを使用したい場合は、配列に変換する必要がある。
※ちなみにlength
プロパティは使用できる。(NodeListにもlengthプロパティが存在するため)
というか配列風オブジェクトはlengthを使えることが定義の1つらしい。
// NodeListに含まれるノードの数を取得
console.log(elms.length);
NodeList - Web API | MDN 👻 > forEach()とかも使えるのか..
🐳 [].slice
Array.prototype.slice()
メソッドは、配列を切り抜くメソッド。
引数に何も指定しない場合、配列をshallow copyすることができる。
const arr = ['hoge', 'fuga', 'piyo']
const sliceArr1 = arr.slice(2);
const sliceArr2 = arr.slice(1,3);
const copyArr = arr.slice();
console.log(sliceArr1); // ['piyo']
console.log(sliceArr2); // ['fuga', 'piyo']
console.log(copyArr); // ['hoge', 'fuga', 'piyo']
Array.prototype.slice() - JavaScript | MDN
[].slice()
と指定した場合は、空の配列をコピーすることになる。
が、ここでそれは重要ではなくて、**「slice()の引数に何も指定しない場合、配列をshallow copyすることができる。」**だけ覚えれば良いと思われ。
🐳 call()
Function.prototype.call()
メソッドは、、説明が難しい。
MDNによると、
call() はあるオブジェクトに所属する関数やメソッドを、別なオブジェクトに割り当てて呼び出すことができます。
つまり最初の例の場合、Array.prototype
に所属するslice()
メソッドを、引数に指定した配列風オブジェクトのelms
に割り当てて呼び出している。
//配列風オブジェクト
const elms = document.querySelectorAll('.elm');
//そのままではslice()を使えないが、
elms.slice(); // エラー
//call()を使用して、配列風オブジェクトelmsを、配列として呼び出すことでslice()を使える
const elmArr = [].slice.call(elms);
よって実質elms.slice()
が実行されることとなる。
引数なしのslice()メソッドは、配列のshallow copyと同義のため、elms(配列風オブジェクト)の中身をそのままコピーした配列が生成される。→目的の達成 🎉
■補足
call()は第2引数以降に、呼び出し先の関数に渡される引数を指定することができる。
つまり、この場合でslice()に引数を渡したい場合は、
// 配列風オブジェクトを任意の形にsliceして配列に変換
const sliceElmArr = [].slice.call(elms, 1, 3);
のような形で指定ができる。
🐳 ES6以降では
ES6記法が使えるならArray.from()
やスプレッド演算子を使えばおk
//配列風オブジェクト
const elms = document.querySelectorAll('.elm');
//配列に変換
const elmArr1 = Array.from(elms);
const elmArr2 = [...elms];
🐳 おまけ知見
🐠 arguments
配列風オブジェクトの1つ。
すべての関数内(アロー関数を除く)で利用可能なローカル変数であり、関数の引数を参照することができる。
arguments - JavaScript | MDN
const func = function(arg1, arg2) {
console.log(arguments); // [1, 2]
};
func1(1, 2);
🐠 [].sliceは省略形
空配列[]を使用するのは省略形の書き方。slice()を使いたいだけなので以下の書き方でも良い。
const elmArr = Array.prototype.slice.call(elms);
🐳 参考
- JavaScriptの配列風オブジェクトと「[].slice.call()」による配列変換について - このすみ技術メモ
- Array.prototype.slice.call(arguments)とは - console.lealog();
- JavaScript bind,call,apply入門! - Qiita
- Array.prototype.slice() - JavaScript | MDN
- Function.prototype.call() - JavaScript | MDN
- arguments - JavaScript | MDN
/post-1
[].slice.call()とは
Related Posts