JavaScript, как удалить методы-прототипы из объекта данных или заставить объекты работать с Qunit равными - PullRequest
8 голосов
/ 17 декабря 2010

Я начал работать с 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, результат также содержит множество функций, например

"function (iterator, context) {...

Я думаю, что эти функции происходят от меня, рассматривая объект какмассив для присвоения ему.

Есть ли способ вырезать эти функции (или предотвратить их добавление в первую очередь)?

Я думал о том, чтобы сделать

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

есть ли лучший способ?

Ответы [ 3 ]

5 голосов
/ 17 декабря 2010

Проблема в том, что вы используете for...in, который перебирает все, что fields наследует от object. Если вы должны сохранить for...in, вы можете изменить его следующим образом:

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

hasOwnProperty возвращает true, если указанное свойство объекта (а массив равен объект) не наследуется.

4 голосов
/ 17 декабря 2010

Вы можете проверить тип каждого объекта в коллекции, чтобы увидеть, является ли это функцией:

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

Кроме того, не используйте for..in для массивов :

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

То, что у вас есть, не является строго объектом , это - Array объект, который, тем не менее, является объектом, но не в том смысле, что онимеет пары ключ-значение.

Если вы используете ванильный цикл for, вы не будете перебирать цепочку прототипов, как вы делаете с for..in, так что, возможно, выполнение этого может решить вашу проблему.

0 голосов
/ 17 декабря 2010

Вы не должны использовать for in на массивах. Глава 6 JavaScript: Хорошие части дает отличное объяснение:

Поскольку массивы JavaScript действительно объекты, оператор for in может быть используется для перебора всех свойства массива. К несчастью, for in не дает никаких гарантий относительно порядок свойств, и большинство приложения массива ожидают элементы производится в числовом порядке. Кроме того, все еще существует проблема с неожиданные свойства выкапываются из прототипа цепи.

Вместо этого используйте обычный цикл в стиле C for.

...