【问题标题】:How to link two constructors and inherit them as prototype to an Object?如何链接两个构造函数并将它们作为原型继承到对象?
【发布时间】:2018-01-19 14:12:54
【问题描述】:

我正在使用 JavaScript 中的prototypes(我是 JS 新手)并坚持使用以下 JS 代码的 sn-p:

我创建了两个函数:

功能1

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

功能2

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

我继承sample2到sample1的属性如下:

sample1.prototype = sample2; 

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

let test = new sample1;

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

test.uname;

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

问题:

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

注意:以上是使用 Chrome 开发者工具 - 控制台尝试的

谢谢。

【问题讨论】:

  • 你需要调用sample2作为它的一个函数。继承它没有任何意义。 sample1.prototype = new sample2 会工作
  • 只是一个约定,但可以避免很多混乱。如果要像类一样使用函数,则将函数的第一个字符大写.. 例如.. Sample1 而不是 sample1..
  • @JonasW。不完全 - 您需要将 sample2 的原型链与 sample1 的原型链相关联。

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


【解决方案1】:

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

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);

【讨论】:

  • 注意:如果您想使用附加到基类原型的方法,而不仅仅是直接附加到 this 的简单的每个实例属性,则需要 Object.create()。
【解决方案2】:

这是在 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 2014-01-01
    相关资源
    最近更新 更多