【问题标题】:How many times parent object gets created during prototypal inheritance在原型继承期间创建了多少次父对象
【发布时间】:2013-05-23 04:47:47
【问题描述】:

我已经阅读了很多关于原型继承如何工作以及解释器如何遍历原型链来查找属性的文章。

function Man()
{
    this.hands=2;//1
}
function father()
{
    this.name="";
}
father.prototype= new Man();//2

var malay= new father();
var abhik= new father();

现在我的问题是语句 #1 & #2 只被调用一次。那么“abhik”和“malay”应该共享同一个 Man 对象吗? 所以内存中会有 3 个对象。 1.abhik 2.马来语 3.man(双方共享一个实例) 那么按照这种逻辑,更改后的值应该在对象之间共享?

malay.hands=3;
console.log(abhik.hands);
abhik.hands=4;
console.log(malay.hands);

但事实并非如此。 为什么这样 ?

【问题讨论】:

  • 有关如何子类化的更多信息:stackoverflow.com/questions/16063394/… 如果您的实例需要对 Man 进行子类化,而不是在父亲的函数体中调用 Man 在像这样被创建的父亲:Man.call(this);
  • 在马来语上设置 hand 属性的那一刻,您正在覆盖该属性,从原型中隐藏。(格式化,移动)

标签: javascript prototypal-inheritance prototype-programming


【解决方案1】:

您的理解是正确的,有 3 个对象,abhikmalay 都继承自同一个 Man 实例。但是,当您在 malayabhik 对象上设置新的 hands 属性时,您会给它们自己的 hands 属性,它们不再从原型 Man 继承 hands 属性。

插图:

在您第一次创建 malayabhik 之后,这里是您的三个对象的模拟:

father.prototype -> {hands: 2} 
malay -> {name: ""}   // Empty name property, NO hands property
abhik -> {name: ""}   // Empty name property, NO hands property

当您检查malayabhik 上的hands 属性时,解释器将看到没有这样的属性,并将检查原型链并发现它们的父father.prototype 确实有一个hands 属性,因此解释器将报告该值,即2

设置hands 属性后,您的对象如下所示:

father.prototype -> {hands: 2} 
malay -> {name: "", hands: 3}   // Empty name property, OWN hands property
abhik -> {name: "", hands: 4}   // Empty name property, OWN hands property

现在您的对象都有自己的hands 属性。

资源:这是一篇写得很好的(但很长)关于 javascript 继承的文章: http://manuel.kiessling.net/2012/03/23/object-orientation-and-inheritance-in-javascript-a-comprehensive-explanation/

【讨论】:

  • 有详细解释的链接吗? .这是否意味着每次我调用 newfather(),new Man() 都会被调用?
  • @Abhik 在评论中发布了一个链接。和不;一个人只会被创造一次。
  • 不,Man 构造函数只实例化一次。请查看我的更新答案。
【解决方案2】:

如果您需要在实例之间共享原始类型或不可变类型,您可以使用闭包来保留它的值并使用 getter 和 setter 来访问它。

function Man()
{
  var hands=2;
  return {
    getHands:function(){
      return hands;
    },
    setHands:function(number){
      hands=number;
    }
  }
}
function Father(name)
{
    this.name=name;
}
Father.prototype= Man();
malay=new Father("malay");
abhik=new Father("abhik");
malay.setHands(4);
console.log(abhik.getHands());
console.log(malay.getHands());

如果您需要将父亲作为 Man 的实例,您可以执行以下操作:

function Hands(){
  var hands=2;
  return {
    get:function(){
      return hands;
    },
    set:function(number){
      hands=number;
    }
  }
}

function Man(){
  this.age=18;
  this.array=[];
}
Man.prototype.hands=Hands();
function Father(name){
    //take ownership (copy) of every variable
    //defined in the Man function body
    //with this.... prototype defined
    //are still shared among instances
    Man.call(this);
    this.name=name;
}
Father.prototype= new Man();


malay=new Father("malay");
abhik=new Father("abhik");
malay.hands.set(4);
console.log(abhik.hands.get());
console.log(malay.hands.get());
malay.age=34;
console.log(abhik.age);//from Man.age
console.log(malay.age);//from malay.age
delete malay.age;
console.log(malay.age);//from Man.age
malay.array.push(22);
console.log(abhik.array);// is [] but would be [22]
 // if Man.call(this) was not in the Father function
console.log(malay instanceof Man);

【讨论】:

  • 我知道实现。我只是想知道为什么以及如何。还是谢谢你。
  • 我在 5 小时前给出的评论和 sh0ber 的回答中解释了原因。您不能直接将值分配给实例原型中定义的属性。之前没有解释过如何改变“手”原型属性的值。
猜你喜欢
  • 2014-11-26
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 2018-05-09
  • 1970-01-01
相关资源
最近更新 更多