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继承?请建议我做出正确的更改。
继承和原型的新手。
答案 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)。