[英]JavaScript: The Good Parts - chapter 8, function.apply()
對於以下基於“ JavaScript:優質零件”的第84頁的代碼,有人可以解釋為什么使用[1]和[0]嗎? 我知道他們分別提供參數1和0來進行切片,但是這樣做有什么意義呢?
Function.prototype.bind = function (that) {
var method = this;
var slice = Array.prototype.slice;
var args = slice.apply(arguments, [1]); // Why is [1] here?
return function () {
return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
};
};
var x = function () {
return this.value;
}.bind({ value: 666 });
console.log(x()); // Returns 666.
我相信我了解全局-函數x旨在提取value屬性的值 。 然后,我們綁定一個具有值屬性名稱/值對的對象,並執行x函數。 x函數進入所提供的對象,就像該對象的方法一樣,並返回value屬性的值 。
我不了解這是如何實現的(我注意到Crockford准使用666 )。 提前致謝。
apply的第二個參數必須是一個數組,如果[2]改為2,則會發生這種情況
Array.prototype.slice.apply(arguments,2); 未捕獲的TypeError:Function.prototype.apply:參數列表具有錯誤的類型
arguments
是一個烘培的屬性,它代表發送給類似對象數組中的函數的所有參數。 切片此數組將刪除不需要的部分。 在bind的情況下,將that
作為參數傳遞,因此在1之后進行切片將刪除該參數。
結果是
var args = slice.apply(arguments, [1]); // Why is [1] here?
將采用所有發送來綁定的額外參數,例如.bind({},1,2,3,4)將導致args為[1,2,3,4]
接下來,返回一個函數
return function () {
return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
};
that
是要使用的新作用域, method
是最初從bind調用的函數, args.concat
將接受先前檢查的數組,然后添加使用該方法調用的所有參數,其中就是為什么[0]
被用作相對於[1]
其中, that
被傳遞並沒有被用作用於該方法的自變量)。
Function.prototype.apply()
需要兩個參數,對於一個值this
和的陣列 arguments
。 即使只有一個參數,它也需要一個數組。
所以:
slice.apply(arguments, [1]);
幾乎等同於:
arguments.slice(1);
我說這幾乎是因為arguments
不是真正的數組,並且它沒有切片方法,這就是為什么您必須采用時髦的方式。
正如其他人在評論中指出的那樣,您可以改用call
來使其更整潔。 call
預計,該值this
,然后任意數量的附加參數的方式。 這意味着您可以改為:
slice.call(arguments, 1);
假設您有一些函數,不管它做什么,都將其綁定到上下文並傳遞一些參數。
function myFunc(a, b, c) {
}.bind(myContext, arg1, arg2)
現在讓我們看一下.bind
作用:
Function.prototype.bind = function (that) {
var method = this;
var slice = Array.prototype.slice;
var args = slice.apply(arguments, [1]); // Why is [1] here?
apply
接受參數context, [arg1, arg2, ...]
。 所以slice.apply(arguments, [1])
就像調用arguments.slice(1)
。 (如注釋中所述,您可以使用call
並放下數組括號。) 1
的目的是從1
索引開始切片。 that
這是在傳遞是arguments[0]
上下文之后傳遞給.bind
任何參數都將包含在此片中。 因此,您可以調用myFunc.bind(myContext, arg1, arg2)
; 該分slice
會將args
設置為[arg1, arg2]
。
return function () {
return method.apply(that, args.concat(slice.apply(arguments, [0]))); // Why is [0] here?
};
};
這是.bind
返回的函數; 這是當直接調用myFunc(some, params, here)
時實際上將被調用的函數。 在這種情況下, slice
是整個參數列表; 從0切片將返回整個列表,並將其轉換為數組,以便可以將其傳遞到外部apply.
第一個參數從薄片1
下降that
和之后獲得的所有參數。 第二個列表從0
切片,以包含所有傳入的參數。
仔細看看Function.prototype.apply() , arguments對象和slice函數 。
apply
將對象作為調用函數的上下文,並將參數數組的附加可選參數發送給被調用的函數。
slice(0)
通常用於將類似數組的對象轉換為數組。
slice.apply(arguments, [0])
幾乎等同於arguments.slice(0),不同之處在於它將不會更改發送到主函數的參數,但會導致一個新數組,保證是一個數組。
與上面類似,但是將從數組中刪除第一個條目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.