JavaScript中的call()和apply()与bind()有什么区别?

996

我已经知道applycall是相似的函数,它们都可以设置函数的上下文(this)。

不同之处在于我们发送参数的方式(手动 vs 数组)。

问题:

但是什么时候应该使用bind()方法?

var obj = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));

jsbin


15
如果有用户在发表回答或投票前查看主题发起人的声望积分,那并不是你的错 :) - Gabriel Llamas
81
call()apply()都是调用函数的方法,但bind()是创建一个新的函数。使用call()时,需要逐个传递参数;而使用apply()时,则需将参数作为数组传入。如需了解更多细节,请查看相关文档,它们可以完整地回答你的问题。 - Nope
4
有点奇怪,居然还没有关于这个的问题:关于这个,这可能是因为在JavaScript 1.8.5 - ECMA-262第5版中添加了bind(),而另外两个函数则已存在于JavaScript 1.3 - ECMA-262第3版中,例如关于它们的问题,Stack Overflow上有像what-is-the-difference-between-call-and-apply这样的问题。我只是猜测,因为我自己也在思考这个问题。 - Nope
这里的“call”和“Array.prototype.slice.call”中的“call”是同一个吗?后者也很难理解。 - David Spector
obj.call(arg) 和 func(arg) 一样吗?只是前者将 "this" 设置为 obj,以实现类实例方法? - David Spector
显示剩余3条评论
24个回答

0

简单来说,所有方法都用于在常规函数中显式设置上下文(this)

调用:调用在给定上下文上调用函数,并允许逐个传递参数

应用:应用在给定上下文上调用函数,并允许将参数作为数组传递

绑定:绑定通过设置提供的上下文返回一个新函数,并允许逐个传递参数

注意事项:

  1. 调用和应用都类似,唯一的区别是它们期望的参数方式不同
  2. 所述方法不适用于箭头函数

0
JavaScript中call()、apply()和bind()方法之间的第一个区别是它们的执行时间! call()和apply()非常相似,会立即执行,而bind()则创建一个新函数,在以后的任何时间点都必须显式调用! 另一个区别是,在传递参数时,call()允许我们逐个通过逗号分隔传递,apply()允许我们作为参数数组传递,而bind()允许我们同时执行两者! 我已经附上了示例代码!
const person = {
    fullName : function (randomMessage) {
        return `Hello, ${this.firstName} ${this.lastName} ${randomMessage}`;
    }
}

const personOne = {
    firstName : "John",
    lastName : "Doe"
}

const personTwo = {
    firstName : "Jack",
    lastName : "Adhikari"
}

let fullNameBind = person.fullName.bind(personOne, "--Binding");
let fullNameCall = person.fullName.call({firstName : "Sarah", lastName: "Holmes"}, "--Calling");
let fullNameApply = person.fullName.apply(personTwo, ["--Applying"]);

console.log(fullNameBind());
console.log(fullNameCall);
console.log(fullNameApply);

-1

我认为它们的相同之处在于:它们都可以改变函数的this值。它们的区别在于:bind函数将返回一个新函数作为结果;而call和apply方法将立即执行该函数,但apply可以接受一个数组作为参数,并将解析该数组。此外,bind函数可以进行柯里化。


-3

当我们想要为特定上下文分配一个函数时,应该使用bind函数。

var demo = {
           getValue : function(){ 
             console.log('demo object get value       function') 
            }
           setValue : function(){  
              setTimeout(this.getValue.bind(this),1000)           
           }
 }

在上面的例子中,如果我们调用demo.setValue()函数并直接传递this.getValue函数,则它不会直接调用demo.setValue函数,因为setTimeout中的this指向window对象,所以我们需要使用bind将demo对象上下文传递给this.getValue函数。这意味着我们只是传递具有demo对象上下文的函数,而不是实际调用函数。
希望您能理解。
有关更多信息,请参见详细了解JavaScript bind函数

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接