Расширение Object.prototype JavaScript - PullRequest
33 голосов
/ 29 июля 2011

Я не спрашиваю, нормально ли это:

Object.prototype.method = function(){};

Это считается злом почти всеми, учитывая, что оно портит for(var i in obj).

Настоящий вопрос

Игнорирование

  • Некомпетентные браузеры (браузеры, которые не поддерживают Object.defineProperty)
  • Потенциал для столкновения или переопределения свойства

Если у вас есть какой-нибудь невероятно полезный метод, это считается неправильным / неэтичным?

Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* Makes breakfast, solves world peace, takes out trash */ },
  writable: true,
  configurable: true,
  enumerable: false
});

Если вы считаете, что вышеупомянутое неэтично, зачем им вообще реализовывать эту функцию?

Ответы [ 5 ]

22 голосов
/ 29 июля 2011

Я думаю, что это нормально, если это работает в вашей целевой среде.

Также я думаю, что паранойя расширения прототипа преувеличена. Пока вы используете hasOwnProperty() как хороший разработчик, все в порядке. В худшем случае вы перегружаете это свойство в другом месте и теряете метод. Но это твоя вина, если ты это сделаешь.

11 голосов
/ 29 июля 2011

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


В новых версиях Javascript имеется множество функций, связанных со свойствами, например, определение свойства для перечисления / не перечисления, наличие методов получения и установки ... Object.defineProperty существует для предоставления контроля над этим.

Из Документы Mozilla :

Этот метод позволяет точно добавлять или изменять свойство объекта.Нормальное добавление свойств посредством присваивания создает свойства, которые отображаются во время перечисления свойств (для цикла ... в), значения которых могут быть изменены и которые могут быть удалены.Этот метод позволяет изменять эти дополнительные детали по умолчанию.


Эта новая функция в основном требуется для поддержки новых функций, и вы должны использовать ее для своих собственных целей.Возможность изменять Object.prototype является лишь побочным эффектом того, что он также является «нормальным» объектом и таким же злым, как и раньше.

3 голосов
/ 16 сентября 2016

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

Object.prototype не должен быть расширен, по причинам, перечисленным здесь,Если вы действительно хотите расширить его, то сделайте расширения не повторяемыми.

Я понимаю, что это противоречит всем опубликованным передовым методам, но мы действительно должны прекратить «обязывать» .hasOwnProperty()на итерации ключа объекта и использовать полезность прямого наследования объекта от объекта.

3 голосов
/ 29 июля 2011

Ну, в «JavaScript: хорошие части» есть похожая функция, я думаю, что она очень полезна для улучшения базовых объектов javascript (таких как String, Date и т. Д.), Но только для этого.

// Add a method conditionally. from "JavaScript: the good parts"

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
}
0 голосов
/ 31 августа 2016

Короткий ответ: да, вы должны это сделать.

Перед этим необходимо принять несколько мер предосторожности:
1. использование hasOwnProperty при итерации объекта, но это не такНа самом деле, при выполнении итерации объекта, я все равно уже использую hasOwnProperty.
2. Проверьте, существует ли name в Object.prototype.name, это очень безопасно, чтобы избежать конфликта имен.
3. принятьПреимущество Object.defineProperty(), просто добавьте дополнительный защитный слой.

Как видите, это не очень сложно.

Теперь, когда вы позаботились о рисках / недостатках, появятся преимущества:
1. объединение методов в цепочку, это только делает код более читабельным, лаконичным и делает кодирование более приятным.В свою очередь, вы становитесь счастливее, а ваша жизнь легче.
2. решает проблему совместимости браузера, вы все равно выполняете полифилл.

PS:
Не делайте этого при работе с большой командойточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...