Array.prototype.slice.call

瓜瓜東西發表於2014-11-08

在研究某個框架原始碼的時候,看到的。
查了下資料,
1.兩個部分,一個是String.slice()
slice( ) returns a string containing a slice, or substring, of string. It does not modify string。
slice()返回一個子片段,對原先的string沒有影響,還可以用負數當引數。
Example:

  1. //from javascript-the definitive Guide 5th Edition   
  2. var s = "abcdefg";  
  3. s.slice(0,4)    // Returns "abcd"   
  4. s.slice(2,4)    // Returns "cd"   
  5. s.slice(4)      // Returns "efg"   
  6. s.slice(3,-1)   // Returns "def"   
  7. s.slice(3,-2)   // Returns "de"   
  8. s.slice(-3,-1)  // Should return "ef"; returns "abcdef" in IE 4  
//from javascript-the definitive Guide 5th Edition
var s = "abcdefg";
s.slice(0,4)    // Returns "abcd"
s.slice(2,4)    // Returns "cd"
s.slice(4)      // Returns "efg"
s.slice(3,-1)   // Returns "def"
s.slice(3,-2)   // Returns "de"
s.slice(-3,-1)  // Should return "ef"; returns "abcdef" in IE 4

2.Array.slice(start,end)

slice( ) returns a slice, or subarray, of array. The returned array contains the element specified by start and all subsequent elements up to, but not including, the element specified by end. If end is not specified, the returned array contains all elements from the start to the end of array.
返回從start開始到end的子陣列,如果end這個引數沒有被設定,則返回從start開始到最後的陣列元素。
Example:

  1. var a = [1,2,3,4,5];  
  2. a.slice(0,3);    // Returns [1,2,3]   
  3. a.slice(3);      // Returns [4,5]   
  4. a.slice(1,-1);   // Returns [2,3,4]   
  5. a.slice(-3,-2);  // Returns [3]; buggy in IE 4: returns [1,2,3]  
var a = [1,2,3,4,5];
a.slice(0,3);    // Returns [1,2,3]
a.slice(3);      // Returns [4,5]
a.slice(1,-1);   // Returns [2,3,4]
a.slice(-3,-2);  // Returns [3]; buggy in IE 4: returns [1,2,3]

除了正常用法,slice 經常用來將 array-like 物件轉換為 true array。在一些框架中會經常有這種用法。

  1. Array.prototype.slice.call(arguments,0);//將引數轉換成真正的陣列  
Array.prototype.slice.call(arguments,0);//將引數轉換成真正的陣列

call的作用是改變this的指向,就相當於arguments呼叫了,slice這個方法。0就是start=0,end沒指定,所以返回整個arguments,這個時候就轉換成陣列了。
這裡有一個問題,

  1. arguments.slice(0)//為什麼不直接這樣呢,非要用call改下this的指向就可以了?見下文的分析  
arguments.slice(0)//為什麼不直接這樣呢,非要用call改下this的指向就可以了?見下文的分析

==================華麗麗地分割線==============
玉伯的分析

http://lifesinger.org/blog/2010/05/array-prototype-slice/

讀後感: 能用slice方法的,只要有length屬性就行。雖然arguments有length屬性,但是沒有slice方法,所以呢,Array.prototype.slice()執行的時候,Array.prototype已經被call改成arguments了,因為滿足slice執行的條件(有length屬性),所以沒有報錯。感覺有點hack的意思了