8

我已经开始使用 Qunit 对我的代码进行单元测试,但是在比较对象时遇到了惊人的问题。

我正在测试的代码动态创建一个对象:

var fields = ['id','name'];
var result = {};
for (var field in fields)
{
    var name = fields[field];
    result[name] = name;
}

var expected = { id : 'id', name : 'name' };

test(expected, result, "same ?");

这个测试失败了,我可以看到,虽然预期只包含字段 id 和 name,但 result 还包含很多函数,例如

"function (iterator, context) {...

我认为这些功能来自我将对象视为数组以便分配给它。

有没有办法去除这些功能(或首先阻止它们被添加)?

我正在考虑做

result = $.parseJSON($.toJSON(result));

有没有更好的办法?

4

3 回答 3

6

您可以检查集合中每个对象的类型以查看它是否是函数:

if(typeof fields[field] == 'function') continue;

另外,不要for..in在数组上使用:

for(var i = 0; i < fields.length; i++) {
   result[result[i]] = result[i];
}

你所拥有的并不是严格意义上的object,它是一个Arrayobject,它仍然是一个 object,但在它具有键值对的意义上不是。

如果您使用香草for循环,您将不会像使用 那样遍历原型链for..in,因此也许这样做可能会解决您的问题。

于 2010-12-17T03:43:28.453 回答
5

问题是您对 的使用for...in,它正在迭代所有fields继承自object. 如果一定要保留for...in,可以这样修改:

for (var field in fields){
  if( fields.hasOwnProperty( field ) ){
    var name = fields[field];
    result[name] = name;
  }
}

hasOwnProperty如果对象的指定属性(并且数组一个对象)没有被继承,则返回 true。

于 2010-12-17T03:56:33.443 回答
1

你不应该for in在数组上使用。JavaScript: The Good Parts的第 6 章提供了很好的解释:

由于 JavaScript 的数组实际上是对象,因此该for in语句可用于遍历数组的所有属性。不幸的是, for in它不能保证属性的顺序,并且大多数数组应用程序都希望元素按数字顺序生成。 此外,仍然存在从原型链中挖掘出意外属性的问题。

请改用传统的 C 样式for循环。

于 2010-12-17T04:04:02.660 回答