简体   繁体   English

在构造函数中分配原型

[英]Assigning prototype inside constructor

I have this code: 我有这个代码:

var MyClass = function(b) {
    this.a = b;
    this.getA = function() {
        return that.a;
    }
}

var SecondClass = function(b) {
    this.prototype = new MyClass(b);
    this.getB = function() {
        return 6;
    }
}

var a = new SecondClass(2);
console.log(a.getA());

The output tells me that a has no method called getA() 输出告诉我a没有名为getA()的方法

I assumed that doing this.prototype = new MyClass() inside the constructor for SecondClass would cause it to inhert methods from MyClass? 我假设在SecondClass的构造函数中执行this.prototype = new MyClass()会导致它从MyClass的inhert方法?

I'm sure there are better ways to do this, but I am trying to understand the behaviour of the prototype keyword. 我确信有更好的方法可以做到这一点,但我试图理解prototype关键字的行为。

prototype is a special property of the constructor function , not of the instance . prototype构造函数的特殊属性,而不是实例的特性

When you call the constructor function with new Func() , the engine will create a new object which inherits from Func.prototype and then sets this inside the constructor function to refer to the new object. 当您使用new Func()调用构造函数时,引擎将创建一个从Func.prototype继承的新对象,然后在构造函数内部设置this以引用新对象。

So, aside from this.prototype just being an ordinary property, the inheritance already took place when the assignment takes place. 因此,除了this.prototype只是一个普通的属性,继承已经发生在赋值发生时。

Since you are not assigning any methods to MyClass.prototype , you don't have to do anything with prototype inheritance here. 由于您没有为MyClass.prototype分配任何方法,因此您不必在此处对原型继承执行任何操作。 All you have to do is apply MyClass to the newly created instance using .call [MDN] : 您所要做的就是使用.call [MDN]MyClass应用于新创建的实例:

var SecondClass = function(b) {
    MyClass.call(this, b);
    this.getB = function() {
        return 6;
    }
};

However, you should add all methods that are shared by instances to the prototype and then let each instance of SecondClass inherit from it. 但是,您应该将实例共享的所有方法添加到原型中 ,然后让SecondClass每个实例继承它。 This is how a complete setup could look like: 这就是完整设置的样子:

var MyClass = function(b) {
    this.a = b;
}
MyClass.prototype.getA = function() {
    return this.a;
};

var SecondClass = function(b) {
    // call parent constructor (like 'super()' in other languages)
    MyClass.call(this, b);
}
// Setup inheritance - add 'MyClass.prototype' to the prototype chain
SecondClass.prototype = Object.create(MyClass.prototype);
SecondClass.prototype.getB = function() {
    return 6;
};

var a = new SecondClass(2);
console.log(a.getA());

All of this will become easier in ES6 . 所有这一切在ES6中都会变得更容易

A property called "prototype" is only interesting on objects that are functions. 名为“prototype”的属性仅对作为函数的对象感兴趣。 Assigning a value to the "prototype" property in your constructor has no effect (in this case); 为构造函数中的“prototype”属性赋值不起作用(在本例中); what matters would be the "prototype" property of the constructor function itself. 重要的是构造函数本身的“原型”属性。

SecondClass.prototype = new MyClass();

or something. 或者其他的东西。 The prototype object of a constructor is shared among all the instances constructed, so having the prototype vary by a constructor parameter also doesn't make a lot of sense. 构造函数的原型对象在构造的所有实例之间共享,因此通过构造函数参数改变原型也没有多大意义。

Another thing you could do would be to call the "MyClass" constructor from inside "SecondClass": 你可以做的另一件事是从“SecondClass”中调用“MyClass”构造函数:

function SecondClass(b) {
  MyClass.call(this, b);
  this.getB = function() {
    return 6;
  };
}

That would have the effect of making the this that's constructed in the new SecondClass() call be decorated by the "MyClass" constructor. 这将具有使效果this是在构建new SecondClass()调用的“MyClass的”构造进行装饰。 It wouldn't really be inheritance, but you'd get a "getA" function. 它不会真的是继承,但你会得到一个“getA”函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM