使用 filter() 检查碰撞?
Checking for collisions using filter()?
通常我在 JS 中找出问题并不难,但这次我真的需要一些帮助来理解这段代码。 Mary Rose Cook 在她的 space 入侵者游戏中使用了这个逻辑来过滤 bodies 数组以查找与其他 body 的碰撞。
var bodies = [];
...
update: function () {
// bodies is an array of all bodies in the game
var bodies = this.bodies;
var notCollidingWithAnything = function (b1) {
return bodies.filter(function(b2) { return colliding(b1, b2); }).length === 0;
};
this.bodies = this.bodies.filter(notCollidingWithAnything)
// ...insert function to draw the bodies that are in the new bodies array...
}
谁能解释一下 this.bodies.filter(notCollidingWIthAnything) 在不向参数函数传递任何参数的情况下是如何工作的?编译器如何知道将数组的每个元素与数组的其他元素进行检查?请指导我了解编译器中究竟发生了什么,以便我能够理解这一点。
Can someone please explain how this.bodies.filter(notCollidingWIthAnything)
works without passing in any parameters to the argument function? How does the the compiler know to check each element of the array against each other element of the array?
编译器(好吧,JavaScript 引擎) 不知道如何调用 notCollidingWIthAnything
与元素; Array#filter
确实如此。
notCollidingWIthAnything
是对函数的引用。 (函数在 JavaScript 中是适当的对象,所以我们有对它们的引用,就像我们有对其他对象的引用一样。)代码将该引用传递给 Array#filter
,然后 Array#filter
调用该函数对数组中的每个元素一次,传入元素值(和索引,以及数组;它传递三个参数,尽管我们通常只使用第一个)。然后它使用回调的 return 值来决定是否将元素包含在它构建的新数组中。
这里是 的 Array#filter
简化代码,因此您可以看到发生了什么:
function arrayFilter(callback) {
// Remember this is called with `this` referring to an array-like object
// Create a new, empty array for the result
var result = [];
// Loop through the items
for (var index = 0; index < this.length; ++index) {
// Get the value for this entry
var value = this[index];
// Call the callback
if (callback(value, index, this)) {
// Got a truthy return value, include the value in the result
result.push(value);
}
}
// Return the new array
return result;
}
同样,这是简化的,并不完全正确;有关完全正确的步骤,请参阅 the algorithm in the spec.
这是一个日志示例,可以准确显示谁在做什么:
function arrayFilter(callback) {
console.log("Starting arrayFilter");
var result = [];
for (var index = 0; index < this.length; ++index) {
var value = this[index];
console.log("arrayFilter calling callback with value " + value);
if (callback(value, index, this)) {
console.log("arrayFilter got truthy result, include the value");
result.push(value);
} else {
console.log("arrayFilter got falsy result, don't include the value");
}
}
console.log("arrayFilter done");
return result;
}
function isOdd(value) {
var retval = value % 2 == 1;
console.log("isOdd called with " + value + ", returning " + retval);
return retval;
}
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log("calling `arrayFilter` with `a` as `this`, using `isOdd` callback");
var odds = arrayFilter.call(a, isOdd);
console.log("Resulting array: ", odds);
通常我在 JS 中找出问题并不难,但这次我真的需要一些帮助来理解这段代码。 Mary Rose Cook 在她的 space 入侵者游戏中使用了这个逻辑来过滤 bodies 数组以查找与其他 body 的碰撞。
var bodies = [];
...
update: function () {
// bodies is an array of all bodies in the game
var bodies = this.bodies;
var notCollidingWithAnything = function (b1) {
return bodies.filter(function(b2) { return colliding(b1, b2); }).length === 0;
};
this.bodies = this.bodies.filter(notCollidingWithAnything)
// ...insert function to draw the bodies that are in the new bodies array...
}
谁能解释一下 this.bodies.filter(notCollidingWIthAnything) 在不向参数函数传递任何参数的情况下是如何工作的?编译器如何知道将数组的每个元素与数组的其他元素进行检查?请指导我了解编译器中究竟发生了什么,以便我能够理解这一点。
Can someone please explain how
this.bodies.filter(notCollidingWIthAnything)
works without passing in any parameters to the argument function? How does the the compiler know to check each element of the array against each other element of the array?
编译器(好吧,JavaScript 引擎) 不知道如何调用 notCollidingWIthAnything
与元素; Array#filter
确实如此。
notCollidingWIthAnything
是对函数的引用。 (函数在 JavaScript 中是适当的对象,所以我们有对它们的引用,就像我们有对其他对象的引用一样。)代码将该引用传递给 Array#filter
,然后 Array#filter
调用该函数对数组中的每个元素一次,传入元素值(和索引,以及数组;它传递三个参数,尽管我们通常只使用第一个)。然后它使用回调的 return 值来决定是否将元素包含在它构建的新数组中。
这里是 的 Array#filter
简化代码,因此您可以看到发生了什么:
function arrayFilter(callback) {
// Remember this is called with `this` referring to an array-like object
// Create a new, empty array for the result
var result = [];
// Loop through the items
for (var index = 0; index < this.length; ++index) {
// Get the value for this entry
var value = this[index];
// Call the callback
if (callback(value, index, this)) {
// Got a truthy return value, include the value in the result
result.push(value);
}
}
// Return the new array
return result;
}
同样,这是简化的,并不完全正确;有关完全正确的步骤,请参阅 the algorithm in the spec.
这是一个日志示例,可以准确显示谁在做什么:
function arrayFilter(callback) {
console.log("Starting arrayFilter");
var result = [];
for (var index = 0; index < this.length; ++index) {
var value = this[index];
console.log("arrayFilter calling callback with value " + value);
if (callback(value, index, this)) {
console.log("arrayFilter got truthy result, include the value");
result.push(value);
} else {
console.log("arrayFilter got falsy result, don't include the value");
}
}
console.log("arrayFilter done");
return result;
}
function isOdd(value) {
var retval = value % 2 == 1;
console.log("isOdd called with " + value + ", returning " + retval);
return retval;
}
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log("calling `arrayFilter` with `a` as `this`, using `isOdd` callback");
var odds = arrayFilter.call(a, isOdd);
console.log("Resulting array: ", odds);