我已经知道apply和call是类似的函数,它们设置this(函数的上下文)。

区别在于我们发送参数的方式(manual vs array)

问题:

但是什么时候应该使用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


当前回答

语法

呼叫(thisArg, arg1, arg2, .) (thisArg专心,argsArray) bind(thisArg[, arg1] [, arg2])

Here

thisArg是对象 argArray是一个数组对象 Arg1, arg2, arg3,…是额外的参数

function printBye(message1, message2){ console.log(message1 + " " + this.name + " "+ message2); } var par01 = { name:"John" }; var msgArray = ["Bye", "Never come again..."]; printBye.call(par01, "Bye", "Never come again..."); //Bye John Never come again... printBye.call(par01, msgArray); //Bye,Never come again... John undefined //so call() doesn't work with array and better with comma seperated parameters //printBye.apply(par01, "Bye", "Never come again...");//Error printBye.apply(par01, msgArray); //Bye John Never come again... var func1 = printBye.bind(par01, "Bye", "Never come again..."); func1();//Bye John Never come again... var func2 = printBye.bind(par01, msgArray); func2();//Bye,Never come again... John undefined //so bind() doesn't work with array and better with comma seperated parameters

其他回答

当我们想要分配一个具有特定上下文的函数时,应该使用Bind函数。

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

在上面的例子中,如果我们调用demo.setValue()函数并传递这个。getValue函数,那么它不会调用demo。setValue函数,因为setTimeout中的this指向窗口对象,所以我们需要将演示对象context传递给this。getValue函数使用bind。这意味着我们只是将demo对象的上下文传递给function,而不是实际调用function。

希望你能理解。

更多信息请参考 Javascript绑定函数详细了解

我认为它们的相同之处在于:它们都可以改变函数的this值。它们的区别是:绑定函数将返回一个新函数作为结果;call和apply方法将立即执行函数,但apply可以接受数组作为参数,并且它将解析分离的数组。绑定函数也可以是curiling。

当您希望稍后在特定上下文中调用该函数(在事件中很有用)时,请使用.bind()。当您希望立即调用函数并修改上下文时,请使用.call()或.apply()。

Call/apply立即调用该函数,而bind返回的函数在稍后执行时将具有用于调用原始函数的正确上下文设置。这样你就可以在异步回调和事件中维护上下文。

我经常这样做:

function MyObject(element) {
    this.elm = element;

    element.addEventListener('click', this.onClick.bind(this), false);
};

MyObject.prototype.onClick = function(e) {
     var t=this;  //do something with [t]...
    //without bind the context of this function wouldn't be a MyObject
    //instance as you would normally expect.
};

我在Node.js中广泛使用它,用于我想要传递成员方法的异步回调,但仍然希望上下文是启动异步操作的实例。

bind的简单实现如下所示:

Function.prototype.bind = function(ctx) {
    var fn = this;
    return function() {
        fn.apply(ctx, arguments);
    };
};

还有更多关于它的内容(比如传递其他参数),但您可以阅读更多关于它的内容,并查看MDN上的实际实现。

它允许设置该函数的值,而不依赖于函数的调用方式。这在处理回调时非常有用:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(sayHello.bind(obj), 1000);

要用call实现相同的结果,应该是这样的:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);

Call, Apply和Bind之间的基本区别是:

如果您希望执行上下文出现在图的后面,则将使用Bind。

Ex:

var car = { 
  registrationNumber: "007",
  brand: "Mercedes",

  displayDetails: function(ownerName){
    console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
  }
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**

假设我想在其他变量上使用这个方法

var car1 = car.displayDetails('Nishant');
car1(); // undefined

在你应该使用的其他变量中使用car的引用

var car1 = car.displayDetails.bind(car, 'Nishant');
car1(); // Nishant this is your car 007 Mercedes

让我们讨论bind函数的更广泛使用

var func = function() {
 console.log(this)
}.bind(1);

func();
// Number: 1

为什么?因为现在func与编号1绑定,如果我们不使用bind,它将指向全局对象。

var func = function() {
 console.log(this)
}.bind({});

func();
// Object

当您希望同时执行语句时,将使用Call、Apply。

var Name = { 
    work: "SSE",
    age: "25"
}

function displayDetails(ownerName) {
    console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE

// In apply we pass an array of arguments
displayDetails.apply(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE