如題,在一些代碼中咱們常常會看到
Array.prototype.slice.call(arguments)
或者[].slice.call(arguments)
這段代碼,那這段代碼到底作了什麼呢?咱們就來探尋一下javascript
首先來看一段代碼:java
function foo() {
console.log(arguments)
console.log(Array.prototype.slice.call(arguments))
}
foo(1,2,3)
複製代碼
在這個 foo
函數中咱們打印了 arguments
以及咱們常常看到的這段代碼Array.prototype.slice.call(arguments)
,那它們的結果確定你們都知道:es6
foo(1,2,3);
// {0:1,1:2,2:3,length:3}
// [1,2,3]
複製代碼
大概是這樣的,並且咱們也知道arguments
是一個array-like
(類數組)對象,具體解釋能夠在MDN查看 ,那爲何通過了上述代碼以後就變成了真正的數組了呢?數組
咱們首先來明確一個事情,就是當你經過app
object.method()
複製代碼
來使用一個方法的時候,object
自動成爲當前方法method
的this
值,因此當像以下代碼那樣使用slice()
方法的時候:函數
[1,2,3].slice()
複製代碼
[1,2,3]
自動變成了slice()
方法的this
.這個是程序定義的,咱們若是想要修改,就須要使用 call
或者apply
或者bind
(他們之間的區別請看todo),這裏咱們使用 call
來演示:ui
[1,2,3].slice.call([2,3,4]) //[2,3,4]
// 這樣寫是無心義的只是做爲call的展現
複製代碼
那麼回到問題上來,咱們知道arguments
是個類數組對象了,若是將它做爲 slice()
的this
值,程序會如何處理呢?
在這裏,slice 方法會認爲類數組對象已經知足它自身運行的須要(有length屬性,有數字做爲key的鍵值對),因此 slice
方法會正常運行,而後獲得的結果就是返回一個真正的數組對象。this
若是咱們將 arguments 改成其餘的值,那麼會發生什麼呢?spa
Array.prototype.slice.call(123); // []
Array.prototype.slice.call("123"); // ["1", "2", "3"]
Array.prototype.slice.call(true); // []
Array.prototype.slice.call(null); // error
Array.prototype.slice.call(undefined); // error
Array.prototype.slice.call({foo:"foo",bar:"bar",length:2}); // [empty × 2]
複製代碼
那除了這樣的方式將一個其餘類型的值轉化爲數組還有沒有其餘簡便的辦法呢?(在函數中)
咱們就可使用 es6 中的 ...rest
參數了:prototype
function bar(...rest) {
console.log(rest)
}
bar() // []
bar(1,2,3) //[1,2,3]
// 下面的兩種方式也是可行的
function baz() {
console.log(Array.from(arguments))
console.log([...arguments])
}
baz(3,4,5)
複製代碼
推薦在之後的函數中使用 ...rest
參數來替換 arguments
局部參數。
Array.prototype.slice.call(arguments)
可使一些類數組對象轉換爲對象,從而使用數組的方法來解決一些問題。