JavaScript中的call() & apply()和bind()有何区别?
JavaScript中的call() & apply()和bind()有何区别?
我已经知道apply
和call
是相似的函数,其设置函数的上下文(context)。
区别在于我们发送参数的方式(手动 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));
admin 更改状态以发布 2023年5月22日
它们都将 this 添加到函数(或对象)中,区别在于函数调用(见下文)。
call将 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" person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"
bind将 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"
或者像这样:
... var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world"); helloFunc(); // output: Jim Smith says hello world"
apply与call类似,但它接受一个类似数组的对象,而不是逐一列出参数:
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"
当您想要在以后使用某个特定上下文调用函数时,请使用.bind()
,这在事件中非常有用。当您想立即调用函数并修改上下文时,请使用.call()
或.apply()
。\n\ncall/apply
会立即调用函数,而bind
返回一个函数,稍后执行该函数时,将为调用原始函数设置正确的上下文。这样,您就可以在异步回调和事件中保持上下文。\n\n我经常这样做:
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. };
\n\n我在Node.js中广泛使用它作为异步回调的成员方法传递,但仍希望上下文是启动异步操作的实例。\n\n一个简单而天真的绑定实现可能是这样的:
Function.prototype.bind = function(ctx) { var fn = this; return function() { fn.apply(ctx, arguments); }; };
。\n\n还有其他更多内容(例如传递其他参数),但您可以阅读更多信息并查看MDN上的真实实现。