无法理解Javascript Koans中的反射测试

时间:2012-02-17 03:27:19

标签: javascript reflection

测试本身已经有一个答案,可以找到here,但我似乎无法弄明白为什么答案是正确的。

给我带来麻烦的test部分是:

var keys = [];
var fruits =  ['apple', 'orange'];
for(propertyName in fruits) {
    keys.push(propertyName);
}
ok(keys.equalTo(['__', '__', '__']), 'what are the properties of the array?');

(显然)正确答案,如上述相关问题所述

ok(keys.equalTo(['0', '1', 'fruits.prototype'), 'what are the properties of the array?');

我尝试插入答案 - 修复了语法错误 - 我的测试仍然失败。

在同一个测试文件中,另一个测试几乎相同,答案就是我所期望的:

test("property enumeration", function() {
    var keys = [];
    var values = [];
    var person = {name: 'Amory Blaine', age: 102, unemployed: true};
    for(propertyName in person) {
        keys.push(propertyName);
        values.push(person[propertyName]);
    }
    ok(keys.equalTo(['name','age','unemployed']), 'what are the property names of the object?');
    ok(values.equalTo(['Amory Blaine',102,true]), 'what are the property values of the object?');
});

我可以在这两个测试之间看到的唯一区别是第二个是使用对象而不是数组。

我从第一个测试中运行代码(在单元测试框架之外)并输出keys的值,它显示为["0","1"] - 我期望的。这个隐藏的第三个值在哪里,我该如何访问它?

所以,我想我最终有两个问题:

  1. 为什么其他问题的答案对我不起作用?
  2. 第一次测试和第二次测试有什么不同?

1 个答案:

答案 0 :(得分:2)

免责声明:我很确定这是对的,但没有费心去测试它。你可以尝试我的答案吗,因为你已经开始测试了吗?

查看GitHub上的文件,有一个名为koan.js的帮助程序脚本。我假设它在测试之前被加载,因为我懒得自己运行它们:P。 (它位于support目录中。)

在此文件中,在所有阵列上都定义了一个名为equalTo的方法:

Array.prototype.equalTo = function(compareTo) { ... }

所以问题的答案是:

  1. 因为对另一个问题的回答是错误的。完全被误导了。等
  2. 因为该方法是在Array上定义的,而不是Object
  3. 似乎有点没什么吸引力。

    如果在原型上定义这样的函数,它将被所有数组继承。尝试在控制台中定义类似的内容,然后评估[].equalTo。然后,为了更多的乐趣,尝试类似的东西:

    for (x in []) console.log(x)
    

    由于此方法是在原型上定义的,因此循环也会迭代它。所以答案是测试可能是0, 1, 'equalTo'。但是,如果您使用带有hasOwnProperty检查的for循环,它自然不会迭代该方法。

    这实际上是关于不使用for in迭代数组的对象课程:)。你永远不会知道什么会潜入......巧合的是,这就是为什么prototype.js失败了,尽管它实际上是一个很好的框架。