Почему здесь a.y undefined?
function A() {}
A.prototype.x = 10;
var a = new A();
alert(a.x); // 10
A.prototype = {
x: 20,
y: 30
};
alert(a.y) // undefined
- Почему он делегирует
old prototype of a.x
, а не новее
один?
- Почему
a.y
выбрасывание undefined
через него устанавливается в prototype
?
Ответы
Ответ 1
Это происходит из-за того, что вы установили A.prototype = obj
Вместо добавления свойств к объекту, который наследуется a
, вы создали совершенно новый объект как A.prototype
, и этот не наследуется a
Рассмотрим,
function A() {}
A.prototype.x = 10;
var p1 = A.prototype; // keep reference to this
var a = new A();
A.prototype = {x: 20, y: 30};
Object.getPrototypeOf(a) === A.prototype; // false, not the new prototype
Object.getPrototypeOf(a) === p1; // true, the old prototype
// however
var b = new A();
Object.getPrototypeOf(b) === A.prototype; // true, this is the new prototype
Если вы внесли изменения в свойства старого прототипа (который я назвал p1
), они были бы унаследованы a
Ответ 2
Вы только что создали новый объект-прототип для класса "A", старый экземпляр A
var a = new A();
... скопировал существующий объект прототипа reference для экземпляра. Этот старый прототип -объект является его собственным объектом и не уничтожается, потому что экземпляр "A" содержит эту ссылку.
Если вы хотите определить "y", вам нужно снова создать объект , используя новый, новый экземпляр будет использовать объект, который вы запросили для прототипа, - и этот экземпляр имеет "y".
http://jsfiddle.net/ejseLum9/
Ответ 3
Почему он делегирует старый прототип a.x, а не новый? Почему a.y бросает undefined через него, установленный в прототипе?
Вы создали полностью new prototype object
. объекты, созданные уже до изменения свойства прототипа, будут иметь старую ссылку, а новый objects
будет иметь новый prototype
.
// was before changing of A.prototype
a.[[Prototype]] ----> Prototype <---- A.prototype
// became after
A.prototype ----> New prototype // new objects will have this prototype
a.[[Prototype]] ----> Prototype // it will still reference to old prototype
Правило большого пальца, prototype
задается момент создания объекта, а затем вы не можете изменить. Можно добавлять только новые или изменять существующие свойства object’s prototype
.
Однако вы можете сделать обходной путь с помощью свойства __proto__
.
function A() {}
A.prototype.x = 10;
var a = new A();
alert(a.x); // 10
var _newPrototype = {
x: 20,
y: 30
};
A.prototype = _newPrototype; //will fail
alert(a.y) // undefined
A.__proto__ = _newPrototype; //will work
alert(a.x);
alert(a.y);