调用/绑定/应用与原型

odr*_*037 -1 javascript prototype bind call apply

在下面的代码中:

function User(name) {
    this.name = name;
}

var user = new User('Jason Bourne');

User.prototype.sayHi = function() {
    return 'Hi ' + this.name;
};

var sayHello = function() {
    return 'Hello ' + this.name;
};
Run Code Online (Sandbox Code Playgroud)

如果我将对象绑定到 sayHello (sayHello.bind(user)) 或使用 user.sayHi();,这两个函数都会给出相同的结果。

所以我的问题是,是否有理由使用一种方法而不是另一种方法?我想我在某处读到过不鼓励在原型上创建东西,如果是的话为什么?

更正:

我错误地写了 Object.prototype.. 而不是指定 (Object I create).prototype..

zer*_*298 5

您不想使用的原因Object.prototype.sayHi = function(){}是,一旦您使用,Object其原型链中的所有内容都将能够使用sayHi. 这就是原型继承的核心。

将内容添加到您创建的对象的原型中是可以的(并且添加到 被认为是不好的做法Object.prototype)。只要明白,当你这样做时,对象原型链中的任何东西都将能够使用该函数。

function sayHello() {
    console.log("hello");
}

// Bad
Object.prototype.hello = sayHello;
Date.hello(); // Prints hello
Run Code Online (Sandbox Code Playgroud)

Call、Apply 和 Bind 实际上与添加到原型略有不同,Bind 也与 Call 和 Apply 不同。

致电并申请

Function.call()Function.apply()使用您在调用或应用时调用或应用的任何函数。

例如,如果我们想forEach()NodeList

var els = document.querySelectorAll("div");
Array.prototype.forEach.call(els, function(el){
    el.classList.add("someClass");
Run Code Online (Sandbox Code Playgroud)

call 和 apply 之间的最大区别在于,它call接受一个可变参数并apply接受一个数组。

function say() {
    console.log(arguments);
}
say.call(this, "a", "b");
say.apply(this, ["a", "b"]);
Run Code Online (Sandbox Code Playgroud)

绑定

但使用Function.bind()实际上是另一回事。Bind 允许您创建上下文绑定,您可以在需要时从特定上下文调用函数。

function honk() {
    console.log(this.sound);
}

function Car() {
    this.sound = "honk";
}

function Van(){
    this.sound = "beep";
}
var c = new Car();
var v = new Van();

var ftorCar = honk.bind(c);
var ftorVan = honk.bind(v);

ftorCar(); // prints honk
ftorVan(); // prints beep
Run Code Online (Sandbox Code Playgroud)

现在,您可以ftorCar在需要时传递并调用它,并且它将具有正确的范围“绑定”。