本文翻译自:Javascript call() & apply() vs bind()?
I already know that apply
and call
are similar functions which set this
(context of a function). 我已经知道apply
和call
是用于设置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));
#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
创建函数, call
并apply
执行函数,而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: apply与call类似,不同之处在于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