对象的Javascript函数作为参数

卢卡斯·维纳(Lucas Wiener)

假设我们有一个对象定义为

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的期望效果在调用时增加?

编辑:由于更深入的解释,更改了接受的答案。

霍姆斯

考虑这种情况的一种方法是,thisJavaScript中的关键字不是定义它的对象的引用,而是对当前调用者(正在执行调用的对象)的引用。考虑您的示例:

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章