jQuery + extending Object.prototype = "c.replace не является функцией" - PullRequest
5 голосов
/ 20 февраля 2011

Я использую jQuery 1.5 в своем проекте с открытым исходным кодом, и следующая строка также присутствует в моем собственном коде Javascript:

/**
 * Object.isEmpty()
 *
 * @returns {Boolean}
 */
Object.prototype.isEmpty = function ()
{
    /**
     * @deprecated Since Javascript 1.8.5
     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object
     */
    if ( this.__count__ !== undefined )
    {
        return this.__count__ === 0 ? true : false;
    }

    /* Less-aesthetic method, if above method fails */
    for ( var property in this )
    {
        if ( this.hasOwnProperty(property) )
        {
            return false;
        }
    }
    return true;
};

, который просто расширяет Object.prototype, добавляя к нему метод isEmpty () [который проверяет, является ли объект пустым или нет). Из-за этого добавления я получаю ошибку «c.replace не является функцией» в моей консоли Firebug; и мои исследования в Интернете привели меня к сообщению jQuery об отслеживании ошибок , где я «узнал», что расширение Object.prototype не только нарушает jQuery, но и является плохой практикой кодирования. У меня вопрос, почему?

Ответы [ 3 ]

5 голосов
/ 21 февраля 2011

ECMA-262 5-е издание (и JavaScript 1.8.5) имеют способы сделать это с помощью методов Object.defineProperty и Object.defineProperties, установив для поля enumerable свойства false. Это доступно в Chrome 5, Safari 5, Firefox 4 и Internet Explorer 9 или в любой недавней реализации на стороне сервера, которая использует V8 (например, Node.js).

4 голосов
/ 20 февраля 2011

По сути, это потому, что расширение Object.prototype нарушает идиому for ... in.

В Javascript, если у вас есть объект:

var obj = { "foo": 0, "bar": 42 };

Вы можете перебрать его членов, выполнив:

for (var key in obj) {
    // Do Something.
}

Расширение Object.prototype приведет к тому, что расширенные члены будут присутствовать во всех экземплярах объекта, поэтому приведенный выше код будет перебирать больше ключей, чем foo и bar, с вероятными неожиданными результатами.

Вы можете найти скрипку, демонстрирующую проблему здесь .

2 голосов
/ 20 февраля 2011

1) Как добавить (расширить) дополнительные методы (не свойства) в Object?

Пока на вашей странице работает сторонний код, вы не должны этого делать.

2) Если вы можете отличить непосредственных потомков вашего объекта от глобальных, с помощью hasOwnProperty(), почему это плохое кодирование?

Потому что есть вероятность, что другие программисты ленивы, и вы нарушите их код. Рекомендуется не изменять то, что вам не принадлежит . Object.prototype является одной из этих вещей.

Используйте MyLib.isEmpty(obj) или isEmpty(obj) внутри своей области видимости, чтобы не было возможности столкнуться.

...