Ну, оба объекта b1
и b2
имеют одинаковый прототип, а именно экземпляр ObjA
:
ObjB.prototype = new ObjA();
, следовательно, они наследуют и имеют доступ к его свойствам.,b1.objLiteral
и b2.objLiteral
относятся к одному и тому же объекту:
![enter image description here](https://i.stack.imgur.com/RFH7A.png)
и
> b1.objLiteral === b2.objLiteral
true
Чтобы исправить это, необходимо создатьновый объект каждого экземпляра.Обычно это делается путем вызова «родительского» конструктора внутри «дочернего» конструктора:
function ObjB() {
ObjA.call(this);
this.propB = 2;
}
ObjA.call(this)
вызовет ObjA
, а внутри этой функции this
будет ссылаться на аргумент, переданный вcall
[MDN] , в данном случае новый экземпляр ObjB
:
![enter image description here](https://i.stack.imgur.com/l7rVD.png)
Как вы можете видеть, objLiteral
теперь является свойством каждого экземпляра:
> b1.objLiteral === b2.objLiteral
false
Во-первых, чтобы избежать этой путаницы, установите экземпляр родительского конструктора в качестве прототипа дочернего элемента.конструктор следует избегать.Что если родительский конструктор ожидает аргументы, специфичные для экземпляра?Что бы вы передали ObjA
в этом случае?
Лучше установить прототип дочернего конструктора равным прототипу родительского конструктора (с одним уровнем косвенности) и вызватьродительский конструктор, как указано выше:
function inherit(Child, Parent) {
var Tmp = function() {};
Tmp.prototype = Parent.prototype;
Child.prototype = new Tmp();
Child.prototype.constructor = Child;
}
inherit(ObjB, ObjA);
Tmp
, чтобы предотвратить расширение Parent.prototype
, если вы расширите Child.prototype
позже.
Относительно propA
:
Это «работает», потому что вы присваиваете ему новое значение.
Здесь снова объекты, после присвоения свойств x.objLiteral
и x.propA
.Вы можете видеть, что объекты не имеют собственного свойства objLiteral
, но имеют собственное propA
:
![enter image description here](https://i.stack.imgur.com/t3bBh.png)
Если вместо этого вы назначите новое значение *От 1073 * до objLiteral
, например, через
b1.objLiteral = {hello: 42};
b1
теперь будет иметь свое собственное свойство objLiteral
, которое затеняет наследуемое:
![enter image description here](https://i.stack.imgur.com/iUHlL.png)