2013-12-11 3 views
1

Я только что столкнулся с непредвиденной проблемой, пытаясь создать прототип массива для функции, которая эмулирует то, что доступно в .net (linq) под названием SingleOrDefault().Javascript - defineProperty vs Prototype

Хотя прототип функция работала хорошо, я обнаружил, что, когда итерация обычного массива, используя следующий синтаксис для (вар х в у) ... мое имя функции появилось в качестве одного из свойств и сломал мою логику.

В результате некоторых поисковых запросов я пересмотрел функцию (ниже).

Мой вопрос: есть ли код в Текущий блокирует правильный способ расширения объекта Array без каких-либо нежелательных побочных эффектов?

Предыдущая

Array.prototype.singleOrDefault = function (predicate) { 
    var items = applyPredicate(this, predicate); 
    if (items.length > 1) { 
     throw new Error(errorOutput.multipleElements); 
    } 
    return (items) ? items[0] : null; 
}; 

Текущий

Object.defineProperty(Array.prototype, 'singleOrDefault', { 
    value: function (predicate) { 
     var items = applyPredicate(this, predicate); 
     if (items.length > 1) { 
      throw new Error(errorOutput.multipleElements); 
     } 
     return (items) ? items[0] : null; 
    }, 
    enumerable: false 
}); 
+0

Второй синтаксис является относительно новым. В зависимости от того, какую поддержку браузера вам нужно/ожидайте, это может быть не очень практично. –

+0

Просто не используйте 'for (var x in y) {...}', поскольку он не предназначен для использования с массивом, а только с объектами. [для ... in] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) – Andreas

+0

@Andreas. Одна из проблем с тем, что вы никогда не знаешь, работает ли библиотека, если вы не прочитали код. –

ответ

0

Да ваш «текущий» код верен, а не поддерживается старыми браузерами, как предыдущий код, который является недостатком, если вам нужно т.е. поддержка 6/7 (см. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).

Вы можете использовать метод object.hasOwnProperty с «предыдущего» кода для достижения того же эффекта, когда вы итерация:

for (var x in y) { 
    if (y.hasOwnProperty(y[x])) { 
     //would filter out SingleOrDefault in your examples above 
    } 
}