我有一个关于 Typescript 如何为简单类继承生成 javascript 代码的问题。 下面是一些 Typescript 代码,后面是生成的 javascript 代码。
typescript 代码:
class Animal {
constructor(public name: string) { }
move(meters: number) {
alert(this.name + " moved " + meters + "m.");
}
}
class Cat extends Animal {
constructor(name: string) { super(name); }
move() {
alert("run...");
super.move(5);
}
}
生成的 Javascript 代码:
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Animal = (function () {
function Animal(name) {
this.name = name;
}
Animal.prototype.move = function (meters) {
alert(this.name + " moved " + meters + "m.");
};
return Animal;
})();
var Cat = (function (_super) {
__extends(Cat, _super);
function Cat(name) {
_super.call(this, name);
}
Cat.prototype.move = function () {
alert("run...");
_super.prototype.move.call(this, 5);
};
return Cat;
})(Animal);
您将看到生成的 javascript 代码包含一个 __extends(d, b)
。此函数将所有基类属性复制到派生类:d[p] = b[p];
。
我的问题是为什么需要这种复制,只需设置 Cat.prototype = _super;
就可以了,并且与基于 Javascript 原型(prototype)的继承内联。将基本构造函数属性复制到派生构造函数,如 d[p] = b[p];
似乎是在浪费内存。
最佳答案
原型(prototype)上不存在静态属性/函数。 原型(prototype)
仅在创建新
实例时使用。
因此,第一个循环只是简单地复制静态属性(包括函数)。它没有复制 prototype
上的任何内容(因为 for(var v in p)
不包括 prototype
或声明的属性/函数原型(prototype))。
在 JavaScript 中保留 prototype
链的最佳方法是将子类的 prototype
设置为父类(super class)的实例。在上面的例子中,这相当于:
Cat.prototype = new Animal();
这样,当 JavaScript 寻找匹配的属性时,它将通过继承层次正确地遵循原型(prototype)链。
如果直接设置:
Cat.prototype = Animal.prototype
这意味着对 Cat
prototype
的任何运行时更改也会影响 Animal
,因为它们将指向同一个实例(通常是不可取的)。
关于Typescript 生成用于简单类继承的 javascript 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22901249/