應用和呼叫語法和呼叫

每個函式中的 applycall 方法允許它為 this 提供自定義值。

function print() {
    console.log(this.toPrint);
}

print.apply({ toPrint: "Foo" }); // >> "Foo"
print.call({ toPrint: "Foo" }); // >> "Foo"

你可能會注意到上面使用的兩個呼叫的語法都是相同的。即簽名看起來很相似。

但是它們的用法存在細微差別,因為我們正在處理函式並改變它們的範圍,我們仍然需要維護傳遞給函式的原始引數。applycall 都支援將引數傳遞給目標函式,如下所示:

function speak() {
    var sentences = Array.prototype.slice.call(arguments);
    console.log(this.name+": "+sentences);
}
var person = { name: "Sunny" };
speak.apply(person, ["I", "Code", "Startups"]); // >> "Sunny: I Code Startups"
speak.call(person, "I", "<3", "Javascript"); // >> "Sunny: I <3 Javascript"

請注意,apply 允許你傳遞 Arrayarguments 物件(類似陣列)作為引數列表,而 call 需要你分別傳遞每個引數。

這兩種方法讓你可以自由地獲得所需的內容,例如實現 ECMAScript 本機 bind 的不良版本,以建立一個始終被稱為原始函式的物件方法的函式。

function bind (func, obj) { 
    return function () {
        return func.apply(obj, Array.prototype.slice.call(arguments, 1));
    }
}

var obj = { name: "Foo" };

function print() {
    console.log(this.name);
}

printObj = bind(print, obj);

printObj();

這將記錄

bind 功能有很多功能

  1. obj 將用作 this 的值
  2. 將引數轉發給函式
  3. 然後返回值