Почему это Object.defineProperty(), а не this.defineProperty() (для объектов)?

Я работаю над проектом JavaScript, и мне просто интересно, почему экземпляр объекта не наследует defineProperty() и другие методы, вместо того, чтобы вызывать метод суперкласса (суперобъект?) Object.

Я просмотрел MDN docs, и на самом деле существуют "нестандартные" методы свойств.

Но они устарели. Почему переход к методам Object?

Мне кажется, что что-то вроде instance.defineProperty(...) лучше, чем Object.defineProperty(instance, ...). Я бы сказал то же самое и о некоторых других методах объекта.

Ответ 1

Это, чтобы избежать коллизий - в общем, проблемы с объектами, которые не имеют свойства со значением, которое вы ожидаете.
Объекты в JS часто используются в качестве карт-значений ключей, а ключами могут быть произвольные строки - например, __defineGetter__, hasOwnProperty или что-то менее специальное. Теперь, когда вы хотите вызвать такую ​​функцию на неизвестном объекте - например, hasOwnProperty часто используется в общих функциях перечисления, где любой JSON может быть передан, вы никогда не можете быть уверены, есть ли у вас перезаписанное свойство (это может даже не быть быть функцией) или оригинал, который вы хотите, или же объект наследует свойство вообще. Чтобы избежать этой проблемы (или этой ошибки IE), вам придется использовать Object.prototype.hasOwnProperty.call - это уродливо.

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

Вы можете быть счастливы, если в прототипе будет defineProperty, но вы можете безопасно использовать его при работе с известными объектами. Если вы все еще это хотите (как вы знаете, когда использовать, а когда нет), вы можете использовать

Object.defineProperty(Object.prototype, "defineProperty", {
    writable: true,
    enumberable: false,
    value: function(prop, descr) {
        return Object.defineProperty(this, prop, descr); 
    }
});

Ответ 2

Интересно. Единственная причина, по которой я пришел, заключается в том, что людям нравится переписывать прототипы и этот метод "скрытый", подобный этому, может помочь вам избежать некоторых ошибок. Особенно из-за хорошего имени метода, поскольку это, скорее всего, будет перезаписано, чем, например, __defineGetter__.

Похоже, что от этой функции зависит множество функций (ссылка), поэтому имеет смысл сделать ее более глобальной и безопасной в этом контекст.

Ответ 3

Это делается так, чтобы избежать столкновений - помните, каждый метод на Object.prototype также является методом в каждом отдельном пользовательском объекте.

Представьте себе объект, в котором вам нужен пользовательский метод defineProperty, который полностью нарушит работу, когда Object.defineProperty был на своем прототипе.