以对象作为参数的 JavaScript 函数

标签 javascript this

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

var 对象 = {计数器:0;增量: function() { this.counter++; } };

现在,调用对象的增量函数将按预期增加计数器。

object.increment();//object.counter 现在等于 1

让我烦恼的是,我会有一个调用参数函数的函数,计数器不会增加,因为 this 变量指向调用函数的闭包。

函数调用(func) { func(); };调用(对象.增量);//object.counter仍然是1

所以我的问题是,是否有任何方法可以使调用者函数保持 this 变量不变,以便 object.counter 在调用时增加所需的效果?

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

最佳答案

一种思考方式是 JavaScript 中的 this 关键字不是对其定义的对象的引用,而是对当前调用者的引用——正在进行调用的对象。考虑你的例子:

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 始终指向同一个调用者。

Note: bind() also has the ability to perform partial applications of function parameters, which can also be useful.

因此,我们可以通过以下方式创建增量绑定(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);
  }
}

绑定(bind)返回一个函数,该函数将在特定上下文中调用所提供的 fn,并且始终在该上下文中。

Note: once a function has been bound to a context/invoker, you cannot "undo" that binding. Using .call() or .apply() on a bound function will not change 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 中函数如何工作的相同基本概念的不同方式。

关于以对象作为参数的 JavaScript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20020212/

相关文章:

JavaScript 内部函数 & 'this'

javascript - 在 Javascript 中确保 "this"上下文的最佳实践是什么?

javascript - AJAX - 显示 AJAX 结果之间的延迟时间

javascript - Struts2上传多个文件前如何显示选中的文件名?

javascript - 更改 DOM 中的随机元素(无 jQuery)

javascript - 预览后 - 使用 AJAX 和 Fancybox 传递数据

javascript - 将函数内部原型(prototype)分配给函数原型(prototype)对象

javascript - “this”关键字如何工作?

java - 是否需要在同一个类中创建一个类的对象?

javascript - 单击 ReactJS 检索图像的索引