在使用在线 TypeScript 编译器时,我注意到创建者选择在以下方法的帮助下实现继承(我已使该方法更具可读性):
var __extends = function(type, base) {
for (var prop in base) { // why copy the properties?
if (base.hasOwnProperty(prop)) {
type[prop] = base[prop];
}
}
function __() { // <- ?
this.constructor = type;
}
__.prototype = base.prototype.
type.prototype = new __();
};
然后按以下方式使用该方法:
var Item = (function () {
function Item() {
}
return Item;
})();
var Sword = (function (base) {
__extends (Sword, base);
function Sword() {
base.call(this);
}
return Sword;
})(Item);
我很难理解 __extends
方法的实现。
从扩展类型手动复制所有属性的目的是什么?继承原型(prototype)不会解决这个问题吗?
与直接复制的属性相比,在原型(prototype)树中搜索属性是否会降低性能?
第二部分的目的我也看不懂。而不是这样做:
function __() {
this.constructor = type;
}
__.prototype = base.prototype.
type.prototype = new __();
这不能简单地实现为:
type.prototype = base.prototype;
最佳答案
好问题。让我们分解一下。
var __extends = function(type, base) {
// ** Begin static-side inheritance **
for (var prop in base) {
if (base.hasOwnProperty(prop)) {
type[prop] = base[prop];
}
}
// ** End static-side inheritance **
// ** Begin Object.create polyfill **
function __() { // <- ?
this.constructor = type;
}
__.prototype = base.prototype.
// ** End Object.create polyfill **
// ** Prototype setup **
type.prototype = new __();
};
首先是静态端继承。 TypeScript 的类型系统强制要求,如果某些类型具有静态方法,则派生类也具有该方法(或者其签名是基类方法的子类型的方法)。这对于工厂模式之类的东西很有用,例如:
class Car {
static create(name: string, topSpeed: number): Car {
// ...
return new this(/* ... */);
}
}
class RaceCar extends Car {
// RaceCar ignores topSpeed because it goes super fast
static create(name: string): RaceCar {
// ...
return new this(/* ... */);
}
}
class Truck extends Car {
}
function makeTestCar(t: typeof Car) {
return t.create('test', 60);
}
var car = makeTestCar(Car); // returns an instance of Car
var raceCar = makeTestCar(RaceCar); // returns an instance of RaceCar
var truck = makeTestCar(Truck); // OK, even though Truck doesn't explicitly implement 'create'
请注意,在最后一行中,Truck
类通过其基类 Car
获得了它的 create
方法。需要复制,因为 Truck.__proto__
不是 Car
。
接下来我们有 Object.create
polyfill。仅仅编写 type.prototype = base.prototype
是不够的,因为 __proto__
(AKA [[proto]]
) 和 prototype
成员不是一回事。 SO 上的其他答案对原型(prototype)继承进行了更好的概述,因此我将遵从这些答案。
最后一行设置构造函数的原型(prototype),使创建的对象具有正确的__proto__
关于javascript - 属性复制到继承类型的目的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20038289/