应用和调用语法和调用

每个函数中的 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. 然后返回值