在JavaScript中从对象数组访问绑定函数

3
我有一个对象数组,包含对我的类函数的引用(通过.bind()方法绑定)。当我直接访问它们,比如array[3].myFunction时,一切都正常。但是当我尝试通过迭代数组来访问这些函数时,出现了奇怪的行为。我已经尝试过使用Array.forEach()、for-in、for-of和Array.map()函数,但结果总是相同的——我得到了第一个函数四次。我在这里做错了什么?谢谢。

var Container = function() {
  this.function1 = function() {
    console.log('function 1 invoked');
  };
  this.function2 = function() {
    console.log('function 2 invoked');
  };
  this.function3 = function() {
    console.log('function 3 invoked');
  };
  this.function4 = function() {
    console.log('function 4 invoked');
  };
  
  this.array = [
    { key: '1', myFunction: this.function1.bind(this) },
    { key: '2', myFunction: this.function2.bind(this) },
    { key: '3', myFunction: this.function3.bind(this) },
    { key: '4', myFunction: this.function4.bind(this) },
  ];
};

var container = new Container();

// Just printing the results below
console.log('direct access:');
console.log(container.array[3].myFunction);

console.log('forEach:');
container.array.forEach(el => {
  console.log(el.myFunction);
});

console.log('for in:');
for (let i in container.array) {
  console.log(container.array[i].myFunction);
}

console.log('map:')
container.array.map(el => {
  console.log(el.myFunction);
});

PLNKR: http://plnkr.co/edit/mn8iGh4F3GcJXTNWXMiJ?p=preview

这是一个关于IT技术的网站,提供了PLNKR服务,该服务可以帮助开发人员进行代码编辑和调试。如果您需要使用该服务,请点击上面的链接。

1
由于您实际上并没有调用这些函数,因此每次我都只会得到 function () { [native code] }(一个绑定的函数对象)。无法将其与其他函数区分开来。 - Bergi
4
如果你在这些循环中实际调用函数,而不仅仅是记录函数本身,那么就会得到预期的输出。我的猜测是toString()存在一个 bug,至少在我的 Chrome 版本中是如此。你可能需要指出,在 Chrome 中,它每次都会显示function1 的函数体。 - Jacob
1
Chrome的开发者工具中有一些懒惰求值的东西。这里提到了与数组相关的类似错误: https://dev59.com/qW855IYBdhLWcg3w-JQr - Jacob
1
我真的认为Chrome只是让你认为函数的值是错误的;它只是有一个有缺陷的控制台。试着在Firefox中运行。 - Jacob
1
@DanielKucal 这只发生在Chrome浏览器中,请尝试使用其他浏览器。看起来确实是开发工具检查器的一个错误。您可能需要向Google报告此问题。 - Bergi
显示剩余5条评论
1个回答

0

请看下方。所有似乎都在运作。

当你执行console.log(el.myFunction)时,它实际上会打印出handle而不是执行它,所有的handle看起来都是相同的,如function () { [native code] }

当你调用函数而不是el.myFunction()时,你可以看到它们都在调用正确的函数并打印相应的结果。

你可以在下面检查函数调用。

var Container = function() {
  this.function1 = function() {
    console.log('function 1 invoked');
  };
  this.function2 = function() {
    console.log('function 2 invoked');
  };
  this.function3 = function() {
    console.log('function 3 invoked');
  };
  this.function4 = function() {
    console.log('function 4 invoked');
  };
  
  this.array = [
    { key: '1', myFunction: this.function1.bind(this) },
    { key: '2', myFunction: this.function2.bind(this) },
    { key: '3', myFunction: this.function3.bind(this) },
    { key: '4', myFunction: this.function4.bind(this) },
  ];
};

var container = new Container();

// Just printing the results below
console.log('direct access:');
container.array[3].myFunction();

console.log('forEach:');
container.array.forEach(el => {
  el.myFunction();
});

console.log('for in:');
for (let i in container.array) {
  container.array[i].myFunction();
}

console.log('map:')
container.array.map(el => {
  el.myFunction();
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接