JavaScript中的Array.prototype.slice.call(arguments)能將有length屬性的對象轉換為數組(特別注意: 這個對象一定要有length屬性). 但有一個例外,IE下的節點集合它不能轉換(因為IE下的dom對象是以com對象的形式實現,js對象和com對象不能進行轉換)
首先,我們來看看JavaScript中的slice用法, 在JavaScript中Array是一個類,slice是此類中的一個方法,slice的中文意思是 ‘截取’
一個是String.slice => 返回值是字符串
一個是Array.slice => 返回值是數組
Array.prototype.slice.call(arguments)能夠將具有length屬性的arguments轉換為數組, 我們可以理解為就是 arguments.toArray().slice()
所以,這個過程我們是不是可以理解為 Array.prototype.slice.call(arguments)的實現過程就是把傳入進來的具有length屬性的第一個參數arguments轉換為數組,再調用它的slice(截取)方法
這個Array.prototype.slice.call(arguments) 不單有slice方法,還有call方法。 那么call方法又是如何用的呢
我們來看一個用call方法的例子:
var a = function(){ console.log(this); console.log(typeof this); console.log(this instanceof String); } a.call('littleLuke'); 輸出如下 // 'littleLuke' // Object // true
以下是上面的代碼片段在Visual Studio Code中的執行
從上面的代碼片段中,我們可以看到調用了函數a的call方法之后,我們可以看到把call方法中的參數傳入到函數a的作用域中去了,也就是說函數a中的this此時指向的就是它調用的call方法中的參數
我們上面說了,Array.Prototype.slice.call()除了call方法外,還有slice方法,那么JavaScript中Array的slice方法的內部實現是怎樣的呢
Array.prototype.slice = function(start,end){ var result = new Array(); start = start || 0; end = end || this.length; // this指向調用的對象,當用了call后,能夠改變this的指向,也就是指向傳進來的對象,這是關鍵 for(var i = start; i < end; i++) { result.push(this[i]); } return result; }
所以整個過程我們基本就可以分2步進行理解了
Array.prototype.slice.call(arguments)
理解第一步: 其中,arguments是一個具有length屬性的對象, 通過call 這個方法,把arguments 指向了Array.prototype.slice方法的作用域,也就是說通過call方法,讓Array.prototype.slice對arguments對象進行操作
理解第二步: Array.prototype.slice就是對該對象使用Array類的slice方法。但是呢arguments它又不是個Array對象
typeof arguments === "Object" //不是"Array"
所以我們沒法用arguments.slice()方法,這樣是會報錯的。 所以這里,我們需要使用Array.prototype.slice, 它的作用就是第一步把arguments轉換為一個Array對象,第二步對轉換后的Array對象使用slice方法
理解了整個過程后,我們來看一些具體的例子,
下面是我自己在Visual Studio Code中執行的截圖
在文章的結尾,來說兩個在實際開發中比較常用到的通用方法
1. 將函數的實際參數轉換成數組的方法 (3個方法)
方法一 : var args = Array.prototype.slice.call(arguments);
方法二: var args = [].slice.call(arguments);
方法三:
2. 轉換成數組的通用函數