使用 forEach() 时如何将参数 'this' 绑定到数组的每个元素?
How do I bind the parameter 'this' to each element of an array when using forEach()?
语言:Javascript
操作系统:Ubuntu14.04
浏览器:在 Chromium、Chrome、Firefox 中测试。
背景
我正在制作一个 HTML5 Canvas 游戏,其中包含各种可收集的物品。这些项目的超类是 Collectable
,它有一个 render()
函数:
Collectable.prototype.render = function(){
// renders the collectables
}
Collectable
有不同的子类,都将render()
委托给超类。例如:
var Heart = function(x, y) {
Collectable.call(this, x, y);
}
Heart.prototype = Object.create(Collectable.prototype);
我首先创建一个包含我所有收藏品的数组来实例化我的收藏品:
var collectables = [];
var numOfEach = 5;
// IIFE so as to not pollute global scope
(function() {
for (var i = 0; i < numOfEach; i++) {
// TODO: make this cleaner
var heart = new Heart(100, 200);
collectables.push(heart);
var gemBlue = new GemBlue(100, 200);
collectables.push(gemBlue);
var gemOrange = new GemOrange(100, 200);
collectables.push(gemOrange);
}
})();
然后在我的游戏循环文件中,我有一个 renderEntities()
函数,它在我的 objects 上重复调用各个渲染方法:
function renderEntities() {
// render my other objects
...
// render collectables
collectables.forEach(function() {
// test what 'this' is bound to
console.log(this);
// call render method
this.render();
});
}
...但是在这种情况下 this
绑定到 window
因此 this.render
不是函数。
问题
如何将 this
绑定到 collectables
数组的每个单独元素?
我的研究
我已经阅读了 documentation for the bind
function,但恐怕我不知道如何将其应用于 forEach()
和我的匿名函数。
然后我发现 this existing question which explained how forEach
takes an optional parameter to set this
. After reading the documentation on forEach
我尝试了以下但没有成功的结果:
collectables.forEach(function() {
// test what 'this' is bound to
console.log(this);
// call render method
this.render();
}, this);
...这显然与将 this
设置为全局 object.
具有相同的效果
collectables.forEach(function() {
// test what 'this' is bound to
console.log(this);
// call render method
this.render();
}, collectables);
...这让我更接近一点,因为 this
作为一个整体绑定到 collectables 数组,但显然 this.render
仍然不是一个函数。我看不到我可以在 forEach
中使用什么参数来将 this
绑定到数组的每个元素。
我觉得输入所有这些内容后答案会非常简单。我对 this
的概念比较陌生,所以请放轻松!
我还没有找到另一个问题来回答这个问题,或者至少是我能够根据我的知识水平理解的问题。例如,我考虑过以下问题:
- The invocation context (this) of the forEach function call
- Passing scope to forEach
如果我没理解错的话,您希望获得与每个收藏品相关联的 object。在这种情况下,只需为 forEach
循环传递一个参数。在这种情况下,我称该参数为 theObj
,但也许 theCollectable
甚至 c
会更准确。
collectables.forEach(function(theObj) {
// test what 'this' is bound to
console.log(theObj);
// call render method
theObj.render();
});
更新: 您在 forEach
调用中传递的 this
正在将 this
的当前值传递给循环。此时,this
是在window
的范围内执行的,所以this
是window
。如果您不想引用 window,则不需要传递 this
,并且由于 window
是全局的,所以您根本不需要传递 this
,所以我已将其从建议的答案中删除。
更新: MDN 是 JavaScript 文档的重要资源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
.forEach()
工具将三个参数传递给您的回调函数:
- 数组的当前元素;
- 数组的索引;
- 数组本身。
因此:
collectibles.forEach(function(collectible) {
// the parameter "collectible" will be the
// current array element
});
确实没有必要绑定 this
,但如果您确实需要,您可以:
collectibles.forEach(function callback(collectible) {
if (this !== collectible)
callback.call(collectible, collectible);
else {
// body of function
}
});
语言:Javascript
操作系统:Ubuntu14.04
浏览器:在 Chromium、Chrome、Firefox 中测试。
背景
我正在制作一个 HTML5 Canvas 游戏,其中包含各种可收集的物品。这些项目的超类是 Collectable
,它有一个 render()
函数:
Collectable.prototype.render = function(){
// renders the collectables
}
Collectable
有不同的子类,都将render()
委托给超类。例如:
var Heart = function(x, y) {
Collectable.call(this, x, y);
}
Heart.prototype = Object.create(Collectable.prototype);
我首先创建一个包含我所有收藏品的数组来实例化我的收藏品:
var collectables = [];
var numOfEach = 5;
// IIFE so as to not pollute global scope
(function() {
for (var i = 0; i < numOfEach; i++) {
// TODO: make this cleaner
var heart = new Heart(100, 200);
collectables.push(heart);
var gemBlue = new GemBlue(100, 200);
collectables.push(gemBlue);
var gemOrange = new GemOrange(100, 200);
collectables.push(gemOrange);
}
})();
然后在我的游戏循环文件中,我有一个 renderEntities()
函数,它在我的 objects 上重复调用各个渲染方法:
function renderEntities() {
// render my other objects
...
// render collectables
collectables.forEach(function() {
// test what 'this' is bound to
console.log(this);
// call render method
this.render();
});
}
...但是在这种情况下 this
绑定到 window
因此 this.render
不是函数。
问题
如何将 this
绑定到 collectables
数组的每个单独元素?
我的研究
我已经阅读了 documentation for the bind
function,但恐怕我不知道如何将其应用于 forEach()
和我的匿名函数。
然后我发现 this existing question which explained how forEach
takes an optional parameter to set this
. After reading the documentation on forEach
我尝试了以下但没有成功的结果:
collectables.forEach(function() {
// test what 'this' is bound to
console.log(this);
// call render method
this.render();
}, this);
...这显然与将 this
设置为全局 object.
collectables.forEach(function() {
// test what 'this' is bound to
console.log(this);
// call render method
this.render();
}, collectables);
...这让我更接近一点,因为 this
作为一个整体绑定到 collectables 数组,但显然 this.render
仍然不是一个函数。我看不到我可以在 forEach
中使用什么参数来将 this
绑定到数组的每个元素。
我觉得输入所有这些内容后答案会非常简单。我对 this
的概念比较陌生,所以请放轻松!
我还没有找到另一个问题来回答这个问题,或者至少是我能够根据我的知识水平理解的问题。例如,我考虑过以下问题:
- The invocation context (this) of the forEach function call
- Passing scope to forEach
如果我没理解错的话,您希望获得与每个收藏品相关联的 object。在这种情况下,只需为 forEach
循环传递一个参数。在这种情况下,我称该参数为 theObj
,但也许 theCollectable
甚至 c
会更准确。
collectables.forEach(function(theObj) {
// test what 'this' is bound to
console.log(theObj);
// call render method
theObj.render();
});
更新: 您在 forEach
调用中传递的 this
正在将 this
的当前值传递给循环。此时,this
是在window
的范围内执行的,所以this
是window
。如果您不想引用 window,则不需要传递 this
,并且由于 window
是全局的,所以您根本不需要传递 this
,所以我已将其从建议的答案中删除。
更新: MDN 是 JavaScript 文档的重要资源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
.forEach()
工具将三个参数传递给您的回调函数:
- 数组的当前元素;
- 数组的索引;
- 数组本身。
因此:
collectibles.forEach(function(collectible) {
// the parameter "collectible" will be the
// current array element
});
确实没有必要绑定 this
,但如果您确实需要,您可以:
collectibles.forEach(function callback(collectible) {
if (this !== collectible)
callback.call(collectible, collectible);
else {
// body of function
}
});