簡體   English   中英

JavaScript:優良部件-第8章,function.apply()

[英]JavaScript: The Good Parts - chapter 8, function.apply()

對於以下基於“ JavaScript:優質零件”的第84頁的代碼,有人可以解釋為什么使用[1][0]嗎? 我知道他們分別提供參數10來進行切片,但是這樣做有什么意義呢?

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.


TL; DR

第一個參數從薄片1下降that和之后獲得的所有參數。 第二個列表從0切片,以包含所有傳入的參數。

文檔和上下文

仔細看看Function.prototype.apply()arguments對象slice函數

apply將對象作為調用函數的上下文,並將參數數組的附加可選參數發送給被調用的函數。

片(0)

slice(0)通常用於將類似數組的對象轉換為數組。

slice.apply(arguments, [0])幾乎等同於arguments.slice(0),不同之處在於它將不會更改發送到主函數的參數,但會導致一個新數組,保證是一個數組。

片(1)

與上面類似,但是將從數組中刪除第一個條目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM