TypeScript中的扩展如何工作? [英] How does extends in TypeScript work?
问题描述
以下TypeScript代码:
The following TypeScript code:
class BaseClassWithConstructor {
private _id: number;
constructor(id: number) {
this._id = id;
}
}
class DerivedClassWithConstructor extends BaseClassWithConstructor {
private _name: string;
constructor(id: number, name: string) {
this._name = name;
super(id);
}
}
生成以下JavaScript代码:
Generates the following JavaScript code:
var __extends = (this && 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 BaseClassWithConstructor = (function () {
function BaseClassWithConstructor(id) {
this._id = id;
}
return BaseClassWithConstructor;
})();
var DerivedClassWithConstructor = (function (_super) {
__extends(DerivedClassWithConstructor, _super);
function DerivedClassWithConstructor(id, name) {
this._name = name;
_super.call(this, id);
}
return DerivedClassWithConstructor;
})(BaseClassWithConstructor);
extends
似乎是由 __ extends
function。
extends
seems to be implemented by the __extends
function.
正在尝试找出这个函数背后的魔力。我不明白为什么
我们必须将基类中的属性复制到派生类(即 for(var p in b)if(b.hasOwnProperty(p))d [p ] = b [p];
),并使用 __
函数创建一个新对象,并在 b
, __
, d
以及 __的实例
。
Being trying to work out the magic behind this function. I don't understand why
we have to copy properties in the base class to the derived class (i.e. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
), and create a new object using the __
function and hook up the prototypes between the b
, __
, d
and an instance of __
.
这背后的原因是什么?
推荐答案
生成的javascript代码可以分为两部分:
The generated javascript code can be divided in two parts:
for(var p in b)if(b.hasOwnProperty) (p))d [p] = b [p];
用于继承基类的静态属性。实际上在最新版本的类型脚本中,这行代码已被替换为
is for "inheriting" the static properties of base class. Actually in the newest version of type script, this line of code has been substituted with
extendStatics(d,b);
其中 extendStatics
的定义是:
var extendStatics = Object.setPrototypeOf ||
({__ proto::[]} instanceof Array&& function(d,b){d .__ proto__ = b;})||
函数(d,b){for(var p in b)if(b.hasOwnProperty(p))d [p] = b [p]; };
唯一的区别是在新版本中,操纵 [[prototype]] $ c如果浏览器支持相关行为,则使用$ c>,否则回退到旧的做法,即将每个拥有的属性从基类复制到派生类。
The only difference is that in new version, manipulation of [[prototype]]
is used if related behavior is supported by browsers, otherwise fallback to the old practice, i.e. copying every owned property from base class to derived class.
至于
function __(){this.constructor = d; }
__。原型= b.prototype;
d.prototype = new __();
设置原型
d
到 b
的新实例。但不是直接将 new b(...)
分配给 d.instance
,而是一个虚拟构造函数<$ c $使用c> __ 因为为了设置原型,我们不需要真正调用构造函数 b
,并使用虚拟函数,我们不需要将参数传递给构造函数。请参阅此 SO答案。
It is really a slightly fancier way of setting the prototype
of d
to a new instance of b
. But instead of directly assigning new b(...)
to d.instance
, a dummy constructor __
is used since for the purpose of setting prototype, we don't need the constructor b
to be really invoked, and by using dummy function, we don't need to pass arguments to the constructor. See this SO answer.
这篇关于TypeScript中的扩展如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!