Array.prototype.slice使用拡張

2163 ワード

通常の使用法に加えて、sliceはarray-likeオブジェクトをtrue arrayに変換するためによく使用されます.
名詞解釈:array-like object,Cはlength属性を持つオブジェクト,例えば{0:‘foo’,length:1},{length:‘bar’}.最も一般的なarray-likeオブジェクトはargumentsとNodeListである.
V 8エンジンarrayを表示jsのソースコードは、sliceの内部実装を以下に簡略化することができます.
 
  
function slice(start, end) {
var len = ToUint32(this.length), result = [];
for(var i = start; i < end; i++) {
result.push(this[i]);
}
return result;
}

sliceはthisがarrayタイプである必要はなく、length属性があればよいことがわかります.また、length属性はnumberタイプではなく、数値に変換できない場合、ToUnit 32(this.length)は0を返す.
標準ブラウザでは、sliceの原理を説明しています.しかし、悩ましいieは、いつも私たちに迷惑をかけています.
 
  
var slice = Array.prototype.slice;
slice.call(); // => IE: Object expected.
slice.call(document.childNodes); // => IE: JScript object expected.

以上のコードはieでエラーを報告しました.IEのTridentエンジンがオープンしないのが憎いですが、私たちは推測するしかありません.
 
  
function ie_slice(start, end) {
var len = ToUint32(this.length), result = [];

if(__typeof__ this !== 'JScript Object') throw 'JScript object expected';
if(this === null) throw 'Oject expected';

for(var i = start; i < end; i++) {
result.push(this[i]);
}
return result;
}

これで、わいせつなieを自弁した.
sliceについてもう一つ話題があります.Arrayを使います.prototype.sliceか[].slice ? 理論的には[]Arrayよりも性能的に配列を作成する必要がある.prototypeは少し悪いです.しかし、実際には、この2つの差は多くなく、サイクルでi++を使うか++iを使うかのように、個人的な習慣です.
最後の話題は、パフォーマンスについてです.配列のフィルタリングには、色相を犠牲にする書き方があります.
 
  
var ret = [];
for(var i = start, j = 0; i < end; i++) {
ret[j++] = arr[i];
}

スペースで時間を変える.pushを取り除くと,大きな配列にとって性能の向上が顕著である.
朝早くブログを書いて、気持ちがあまりよくなくて、テーマを残してみんなにあげなければなりません:
 
  
var slice = Array.prototype.slice;
alert(slice.call({0: 'foo', length: 'bar'})[0]); // ?
alert(slice.call(NaN).length); // ?
alert(slice.call({0: 'foo', length: '100'})[0]); // ?