在使用在线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
方法的实施
从扩展类型手动复制所有属性的目的是什么?不会继承原型来处理那个吗?
在原型树中搜索属性而不是直接复制属性时是否存在性能损失?
第二部分我也无法理解其目的。而不是这样做:
function __() {
this.constructor = type;
}
__.prototype = base.prototype.
type.prototype = new __();
这不能简单地实现为:
type.prototype = base.prototype;
答案 0 :(得分:3)
扩展副本原型和静态成员(浅层副本)。静态是Parent.things和原型是Parent.prototype.things prototype.things的复制方式是Object create的poly填充如何工作。
var __extends = this.__extends || function (d, b) {
//Copies Item.things to Sword.things
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
//Copies Item.prototype.things to Sword.prototype.things
//this is a polyfill for Object.create
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Sword = (function (_super) {
__extends(Sword, _super);
function Sword() {
_super.apply(this, arguments);
}
return Sword;
})(Iten);
考虑以下打字稿:
class Item {
public static DAMAGE = 0;
};
在JavaScript中,这将是:
var Item = (function () {
function Item() {
}
Item.DAMAGE = 0;
return Item;
})();
我如何使用静态损伤?请参阅以下示例(simplefied JS);
//Using static to make general getters and setters
var Item = function(damage){
this._data = [];
this.set(Item.DAMAGE,damage)
};
Item.DAMAGE=0;
Item.prototype.get=function(dataIndex){
return this._data[dataIndex];
};
Item.prototype.set=function(dataIndex,val){
//maybe execute Item.rules[dataIndex].set(val) for validating value
this._data[dataIndex] = val;
return val;
};
var i = new Item(22);
//I could get damage using i.get(0)
//but the following reads more easily
i.get(Itesm.DAMAGE);
关于构造函数,原型,继承,混合和这个值的介绍:https://stackoverflow.com/a/16063711/1641941
答案 1 :(得分:3)
好问题。让我们打破这个。
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
类通过其基类create
获得了Car
方法。需要进行复制,因为Truck.__proto__
不是 Car
。
接下来我们有Object.create
polyfill。写type.prototype = base.prototype
是不够的,因为__proto__
(AKA [[proto]]
)和prototype
成员不是一回事。关于SO的其他答案给出了原型继承的更好的概述,所以我会推迟那些。
最后,最后一行设置构造函数的原型,以便创建的对象具有正确的__proto__