Square是否正确地从Rectangle继承?

时间:2015-09-27 07:37:13

标签: javascript jquery

function Rectangle(length, width) {
    this.length = length;
    this.width = width;
}

Rectangle.prototype.getArea = function() {
    return this.length * this.width;
};

function Square(size) {
    this.length = size;
    this.width = size;
}

Square.prototype = new Rectangle();

那是我的代码。

Square是否正确地从Rectangle继承?请建议我做出正确的更改。

继承和原型的新手。

1 个答案:

答案 0 :(得分:4)

  

Square是否正确地从Rectangle继承?

不,但它很接近。以下是Square的更改:

function Square(size) {
    Rectangle.call(this, size, size);
}

Square.prototype = Object.create(Rectangle.prototype);
Square.prototype.constructor = Square;

调用Rectangle创建Square的原型是一种可悲的常见反模式;如果它实际上与我们在做这个时没有给出的参数做了什么呢?

相反,您使用Rectangle.prototype创建一个使用Object.create作为原型的对象。然后更新该原型上的constructor属性,使其指向正确的函数。然后,当您实际拥有要初始化的对象时(例如,在Square函数中),您从Rectangle调用Square来初始化其位,然后再执行任何初始化Square之后需要。

由于它有点冗长,在我切换到ES2015 class语法之前,我使用了一个名为Lineage的辅助脚本。创建原型的那一点可以被隔离成一个函数,这也让我们有机会通过解决它遗漏的事实来支持IE8 {/ 1}}:

Object.create

然后

function derivePrototype(parent, child) {
    var proto, ctor;
    if (Object.create) {
        proto = Object.create(parent.prototype);
    } else {
        ctor = function ctor() { };       // * See note
        ctor.prototype = parent.prototype;
        proto = new ctor;
        ctor = null;
    }
    proto.constructor = child;
    return proto;
}

* Square.prototype = derivePrototype(Rectangle, Square); 在IE8上创建了两个函数(details),但它没有任何保留,并且该函数确实得到了一个名称。

当然,您可以使用ES2015 +:

ctor = function ctor() { };

现在所有主要的现代浏览器都支持这种原生(2019年),但当然,像Internet Explorer这样的老浏览器不支持(甚至不是IE11),所以如果你需要针对旧版浏览器,你需要进行迁移(例如,像Babel)。