JavaScript call()和apply()与bind()?

本文翻译自:Javascript call() & apply() vs bind()?

I already know that apply and call are similar functions which set this (context of a function). 我已经知道applycall是用于设置this相似函数(函数的上下文)。

The difference is with the way we send the arguments (manual vs array) 区别在于我们发送参数的方式(手动vs数组)

Question: 题:

But when should I use the bind() method ? 但是我什么时候应该使用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 jsbin


#1楼

参考:https://stackoom.com/question/12qYL/JavaScript-call-和apply-与bind


#2楼

Use .bind() when you want that function to later be called with a certain context, useful in events. 当您希望以后在特定上下文中调用该函数时,请使用.bind() ,在事件中很有用。 Use .call() or .apply() when you want to invoke the function immediately, and modify the context. 若要立即调用该函数并修改上下文,请使用.apply() .call().apply()

Call/apply call the function immediately, whereas bind returns a function that, when later executed, will have the correct context set for calling the original function. 调用/应用立即调用该函数,而bind返回一个函数,该函数稍后执行时,将具有正确的上下文集来调用原始函数。 This way you can maintain context in async callbacks and events. 这样,您可以在异步回调和事件中维护上下文。

I do this a lot: 我经常这样做:

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.
};

I use it extensively in Node.js for async callbacks that I want to pass a member method for, but still want the context to be the instance that started the async action. 我在Node.js中将它广泛用于异步回调,我想为其传递成员方法,但仍希望上下文成为启动异步操作的实例。

A simple, naive implementation of bind would be like: 一个简单,简单的bind实现是:

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

There is more to it (like passing other args), but you can read more about it and see the real implementation on the MDN . 它还有更多的功能(就像传递其他args一样),但是您可以阅读更多有关它的内容,并查看MDN上的实际实现。

Hope this helps. 希望这可以帮助。


#3楼

It allows to set the value for this independent of how the function is called. 它允许设置值, this独立的功能是如何被调用。 This is very useful when working with callbacks: 这在使用回调时非常有用:

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

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

To achieve the same result with call would look like this: call达到相同的结果看起来像这样:

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

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

#4楼

Assume we have multiplication function 假设我们有multiplication功能

function multiplication(a,b){
console.log(a*b);
}

Lets create some standard functions using bind 让我们使用bind创建一些标准函数

var multiby2 = multiplication.bind(this,2);

Now multiby2(b) is equal to multiplication(2,b); 现在multiby2(b)等于乘法(2,b);

multiby2(3); //6
multiby2(4); //8

What if I pass both the parameters in bind 如果我在绑定中传递了两个参数怎么办

var getSixAlways = multiplication.bind(this,3,2);

Now getSixAlways() is equal to multiplication(3,2); 现在getSixAlways()等于乘法(3,2);

getSixAlways();//6

even passing parameter returns 6; 甚至传递参数返回6; getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

This create a new multiplication function and assigns it to magicMultiplication. 这将创建一个新的乘法函数,并将其分配给magicMultiplication。

Oh no, we are hiding the multiplication functionality into magicMultiplication. 哦,不,我们将乘法功能隐藏在magicMultiplication中。

calling magicMultiplication returns a blank function b() 调用magicMultiplication返回一个空白function b()

on execution it works fine magicMultiplication(6,5); //30 在执行时,它可以正常工作magicMultiplication(6,5); //30 magicMultiplication(6,5); //30

How about call and apply? 打电话和申请怎么样?

magicMultiplication.call(this,3,2); //6

magicMultiplication.apply(this,[5,2]); //10

In simple words, bind creates the function, call and apply executes the function whereas apply expects the parameters in array 简单来说, bind创建函数, callapply执行函数,而apply期望数组中的参数


#5楼

They all attach this into function (or object) and the difference is in the function invocation (see below). 他们都附加到这个函数(或对象)不同的是在函数调用(见下文)。

call attaches this into function and executes the function immediately: 调用附加到这个函数并立即执行的功能:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"

bind attaches this into function and it needs to be invoked separately like this: 绑定附加到这个函数和其需要被这样分开调用:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"

or like this: 或像这样:

...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"

apply is similar to call except that it takes an array-like object instead of listing the arguments out one at a time: applycall类似,不同之处在于apply类似于数组,而不是一次列出一个参数:

function personContainer() {
  var person = {  
     name: "James Smith",
     hello: function() {
       console.log(this.name + " says hello " + arguments[1]);
     }
  }
  person.hello.apply(person, arguments);
}
personContainer("world", "mars"); // output: "James Smith says hello mars", note: arguments[0] = "world" , arguments[1] = "mars"                                     

#6楼

Both Function.prototype.call() and Function.prototype.apply() call a function with a given this value, and return the return value of that function. Function.prototype.call()Function.prototype.apply()使用给定的this值调用一个函数,并返回该函数的返回值。

Function.prototype.bind() , on the other hand, creates a new function with a given this value, and returns that function without executing it. Function.prototype.bind()在另一方面,创建一个具有给定一个新的功能this值,并返回该函数不执行它。

So, let's take a function that looks like this : 因此,让我们采用一个看起来像这样的函数:

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

Now, let's take an object that looks like this : 现在,让我们来看一个看起来像这样的对象:

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

We can bind our function to our object like this : 我们可以像这样将函数绑定到对象:

Obj.log = logProp.bind(Obj);

Now, we can run Obj.log anywhere in our code : 现在,我们可以在代码中的任何位置运行Obj.log

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

Where it really gets interesting, is when you not only bind a value for this , but also for for its argument prop : 真正有趣的地方是,您不仅this绑定一个值,而且为其参数prop绑定:

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

We can now do this : 我们现在可以这样做:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
发布了0 篇原创文章 · 获赞 75 · 访问量 56万+

猜你喜欢

转载自blog.csdn.net/w36680130/article/details/105447068
今日推荐