如何链接两个构造函数并将它们作为原型继承到Object?

时间:2018-01-19 14:12:54

标签: javascript json ecmascript-6 ecmascript-5 prototype-chain

我正在使用JavaScript中的prototypes(我是JS的新手),并坚持使用以下JS代码片段:

我创建了两个函数:

功能1

function sample1() {
    this.uname = "Andrew";
}

功能2

function sample2() {
    this.age = 21;
}

我将sample2的属性继承到sample1,如下所示:

sample1.prototype = sample2; 

到目前为止,一切正常,就像我看到sample1sample2为原型一样。但问题是使用sample1创建了一个包含sample2属性的对象。

let test = new sample1;

现在,尝试访问sample1的属性会得到正确的输出。

test.uname;

但是,尝试访问age会将输出设为undefined

问题:

如何使用age对象访问test属性?

注意:使用Chrome开发者工具 - 控制台

尝试以上操作

感谢。

2 个答案:

答案 0 :(得分:1)

您的unameage属性由构造函数直接在它们初始化的每个实例上创建。在这里使用原型继承是没有意义的。只需运行两个构造函数:

function sample2() {
    this.age = 21;
}
function sample1() {
    sample2.call(this); // runs the other constructor on this instance
    this.uname = "Andrew";
}

当重写方法时,这与super调用非常相似。

  

我正在使用JavaScript中的原型

尚未:-)您的原型对象是空的。

  

我将sample2的属性继承到sample1,如下所示:

sample1.prototype = sample2; 
呃,你不应该这样做。 sample2是一个函数对象,你通常不想要任何东西继承。请注意sample1.prototype是使用new sample1创建的所有实例将继承的 - 它们不是函数。你可能正在寻找

sample1.prototype = Object.create(sample2.prototype);

答案 1 :(得分:1)

这是在ES5中构建原型链的正确方法。

从您的基类开始:

// base class definition
function Sample1(name) {
    this.uname = name;
}

// with an example function stored on the prototype
Sample1.prototype.getName = function() {
    return this.uname;
}

然后使用适当的原型链接子类:

// create the sub-class constructor
function Sample2(name, age) {
    // invokes superclass constructor, passing any params it needs
    Sample1.call(this, name);

    // define subclass per-instance properties
    this.age = age;
}

//
// *** THIS IS THE IMPORTANT BIT ****
//
// create a correctly chained prototype for Sample2
Sample2.prototype = Object.create(Sample1.prototype);

// and then re-associate the correct constructor method
// to assist with debugging, console.log, etc
Sample2.prototype.constructor = Sample2;

// and add methods to it
Sample2.prototype.getAge = function() {
    return this.age;
}

然后,您可以使用新继承的“类”

// pass multiple parameters, and then query the object
var test = new Sample2("Andrew", 21);
console.log(test.getName());
console.log(test.getAge());

// this should show "Sample2"
console.log(Object.getPrototypeOf(test));

// these should both be "true"
console.log(test instanceof Sample2);
console.log(test instanceof Sample1);