我已经知道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


当前回答

所有这些方法背后的主要概念是函数挖掘。

函数借用允许我们在不同的对象上使用一个对象的方法,而不必复制该方法并在两个不同的地方维护它。它是通过使用。调用(),。Apply(),或。Bind(),所有这些方法的存在都是为了显式地在我们所借用的方法上设置此值

Call立即调用函数,并允许您逐个传入参数 一个 Apply立即调用函数,并允许传入参数 作为一个数组。 Bind返回一个新函数,您可以通过调用函数随时调用/调用它。

下面是所有这些方法的示例

let name =  {
    firstname : "Arham",
    lastname : "Chowdhury",
}
printFullName =  function(hometown,company){
    console.log(this.firstname + " " + this.lastname +", " + hometown + ", " + company)
}

CALL

第一个参数,例如调用方法中的name总是一个引用 To (this)变量和后者将是函数变量

printFullName.call(name,"Mumbai","Taufa");     //Arham Chowdhury, Mumbai, Taufa

应用

Apply方法与call方法相同 唯一的区别是,函数参数是在数组列表中传递的

printFullName.apply(name, ["Mumbai","Taufa"]);     //Arham Chowdhury, Mumbai, Taufa

BIND

Bind方法与call方法相同,不同之处在于,Bind返回一个可以稍后通过调用它来使用的函数(不立即调用它)。

let printMyNAme = printFullName.bind(name,"Mumbai","Taufa");

printMyNAme();      //Arham Chowdhury, Mumbai, Taufa

printMyNAme()是调用该函数的函数

下面是jsfiddle的链接

https://codepen.io/Arham11/pen/vYNqExp

其他回答

当您希望稍后在特定上下文中调用该函数(在事件中很有用)时,请使用.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上的实际实现。

想象一下,绑定是不可用的。 你可以简单地构建如下:

var someFunction=...
var objToBind=....

var bindHelper =  function (someFunction, objToBind) {
    return function() {
        someFunction.apply( objToBind, arguments );
    };  
}

bindHelper(arguments);
    function sayHello() {
            //alert(this.message);
            return this.message;
    }
    var obj = {
            message: "Hello"
    };

    function x(country) {
            var z = sayHello.bind(obj);
            setTimeout(y = function(w) {
//'this' reference not lost
                    return z() + ' ' + country + ' ' + w;
            }, 1000);
            return y;
    }
    var t = x('India')('World');
    document.getElementById("demo").innerHTML = t;

function. prototype.call()和function. prototype.apply()都使用给定的这个值调用函数,并返回该函数的返回值。

另一方面,function .prototype.bind()使用给定的这个值创建一个新函数,并返回该函数而不执行它。

让我们取一个这样的函数:

var logProp = function(prop) {
    console.log(this[prop]);
};

现在,让我们选择一个这样的对象:

var Obj = {
    x : 5,
    y : 10
};

我们可以像这样将函数绑定到对象上:

Obj.log = logProp.bind(Obj);

现在,我们可以在代码中的任何地方运行Obj.log:

Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10

真正有趣的是,你不仅为this绑定了一个值,还为它的参数prop绑定了一个值:

Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');

我们现在可以这样做:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10

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

  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);