假设我们有一个对象定义为
var object = {counter: 0; increment: function() { this.counter++; } };
现在,调用对象的递增函数将按预期递增计数器。
object.increment(); //object.counter will now equal to 1
让我感到烦恼的是,我有一个调用参数函数的函数,计数器不会增加,因为this
变量指向的是调用函数的关闭。
function call(func) { func(); }; call(object.increment); //object.counter still 1
所以我的问题是,是否有任何方法可以使调用者函数保持不变,从而使object.counter的期望效果在调用时增加?
编辑:由于更深入的解释,更改了接受的答案。
考虑这种情况的一种方法是,this
JavaScript中的关键字不是对定义它的对象的引用,而是对当前调用者(正在执行调用的对象)的引用。考虑您的示例:
var counter = {counter: 0; increment: function() { this.counter++; } };
如果我们要构造另一个具有类似形式的对象,则可以“借用”该increment
函数:
var startAt100 = {counter:100, increment: counter.increment }
startAt100.increment()
// startAt100.counter == 101
在这里,由于startAt100
对象正在执行调用,因此函数内部this
引用startAt100
。
解决此问题的一种方法是使用该bind()
函数。该bind()
函数接受一个函数并返回该函数的版本,该版本this
始终指向同一调用者。
注意:
bind()
还具有执行功能参数的部分应用程序的功能,这也很有用。
因此,我们可以通过执行以下操作来创建增量的绑定函数:
var boundIncrement = counter.increment.bind(counter);
现在,当我们调用时boundIncrement()
(无论实际调用者是谁)this
,函数内部都将指向该counter
对象。
boundIncrement() // counter.counter == 1
call(boundIncrement) // counter.counter == 2
bind()
为了bind()
更详细地了解,我们可以纯粹在javascript中实现bind函数。它看起来像这样:
function bind(fn, invoker) {
return function() {
return fn.apply(invoker, arguments);
}
}
绑定返回一个函数,该函数将fn
在特定上下文中(始终在该上下文中)调用提供的函数。
注意:一旦将功能绑定到上下文/调用程序,就无法“撤消”该绑定。在绑定函数上使用
.call()
或.apply()
不会改变this
。
另一种方法是更改构造counter
对象的方式。我们可以使用匿名函数创建稳定的作用域,然后创建引用该作用域中变量的闭包。通过执行此操作(而不是使用)this
,您可以创建一个具有要在其中执行的稳定环境的函数。请考虑以下代码:
var counter = (function() {
var state = { counter: 0 }
state.increment = function() { state.counter += 1; };
return state;
})();
counter.increment() // counter.counter == 1
call(counter.increment); // counter.counter == 2
现在,当您调用时counter.increment()
,由于state
创建函数的时间已经到来,所以它将始终指向该特定对象并对其进行突变。
并不是说这是好是坏,这只是理解功能在JavaScript中工作的相同基础概念的另一种方式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句