Почему переназначение Object.prototype не работает? - PullRequest
0 голосов
/ 22 июля 2009

Почему это не работает?

// this one works as I expected, when objSayHello()
Object.prototype.objSayHello = function(){alert('Hello,from OBJECT prototype')};
// NOT working !
Object.prototype ={objSayHello: function(){alert('Hello,from OBJECT prototype')}};

objSayHello();

Ответы [ 5 ]

6 голосов
/ 22 июля 2009
  1. Поскольку вы заменили прототип Object, вы добавляете метод objSayHello к любому объекту, начиная с Object (все объекты).

  2. Не заменять Object.prototype.

То, что вы, вероятно, хотите, это:

someObj.prototype.objSayHello = function(){alert('Hello,from OBJECT prototype')};

Затем позвонить с:

someObj.objSayHello();

То, что вы, похоже, хотите сделать, это:

Object.prototype.objSayHello = function(){alert('Hello,from OBJECT prototype')};

Но это, вероятно, плохая идея, поскольку она будет конфликтовать с итераторами (for...in), если не обрабатываться правильно.

2 голосов
/ 29 января 2010

Object.prototype по какой-то причине является const, что означает только чтение.

1 голос
/ 28 сентября 2012

Отсутствие век неправильно, вы просто не можете переназначить прототипы внутренних типов , таких как Object, Number и т. Д. Вы можете только добавлять новые свойства.

> Number.prototype
  -> Number
> Number.prototype = {}  // Reassignment fails
  -> Object
> Number.prototype
  -> Number
> Number.prototype.objSayHello = 'hi'  // Appending succeeds
  -> 'hi'
> n = new Number(); n.objSayHello
  -> 'hi'

Если вы используете свои собственные объекты, то вы можете обновить или переназначить прототип (примечание: переназначение прототипа повлияет только на новые объекты, но не на существующие).

Не изменяйте интригующие прототипы! Это «плохая вещь», потому что она может вызвать трудно обнаруживаемые побочные эффекты. Если вам нужен базовый тип с новыми свойствами, то создайте новый объект с прототипом, указывающим на базовый объект:

NewObject = function() {};
NewObject.prototype = Object.prototype;
NewObject.prototype.value = 123;

Теперь у вас есть конструктор, который создает новые объекты, которые наследуют свойства как от своего собственного прототипа (например, 'value'), так и от прототипа Object ('toString', 'hasOwnProperty' ...).

1 голос
/ 20 октября 2009
Object.prototype.objSayHello = function(to){alert('Hello, ' + to)};

Выражение выше означает, что вы прикрепили функцию objSayHello ко всем экземплярам, ​​которые будут созданы, поскольку каждый экземпляр является дочерним по отношению к Object, поэтому присоединенное событие связывается со всеми. Например,

var newObject = {};
var anotherNewObject = new Object();

function person(name) {
 this.name = name;
}
var newPerson = new Person("Ramiz");

newObject.objSayHello("newObject");
anotherNewObject.objSayHello("anotherNewObject");
newPerson.objSayHello(this.name);

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

0 голосов
/ 04 июля 2011

Object.prototype на самом деле не настоящий прототип, это всего лишь ссылка. Внутренний объект [[prototype]] используется в качестве прототипа и доступен в некоторых браузерах как свойство proto объекта. Учитывая то, как работают переменные JavaScript, назначение Object.prototype другому объекту изменяет его ссылку, но без изменения внутреннего объекта [[prototype]], поэтому вы получаете обычное свойство с именем prototype, которое ничего не говорит о том, как разрешаются свойства объекта.

Итак, почему это работает, когда вы делаете Object.prototype.myFunction ()? Object.prototype по-прежнему является ссылкой на внутренний [[prototype]], поэтому у него нет проблем с расширением с помощью этой функции, он работает как с любыми другими объектами.

...