TypeScript入门教程 之 classes-emit

TypeScript入门教程 之 classes-emit

 

What's up with the IIFE

为该类生成的js可能是:

function Point(x, y) {
    this.x = x;
    this.y = y;
}
Point.prototype.add = function (point) {
    return new Point(this.x + point.x, this.y + point.y);
};

 

它包装在立即调用的函数表达式(IIFE)中的原因,即

(function () {

    // BODY

    return Point;
})();

 

与继承有关。它允许TypeScript将基类捕获为变量,_super例如

 

var Point3D = (function (_super) {
    __extends(Point3D, _super);
    function Point3D(x, y, z) {
        _super.call(this, x, y);
        this.z = z;
    }
    Point3D.prototype.add = function (point) {
        var point2D = _super.prototype.add.call(this, point);
        return new Point3D(point2D.x, point2D.y, this.z + point.z);
    };
    return Point3D;
})(Point);

 

请注意,IIFE允许TypeScript轻松捕获变量中的基类Point_super并且该基类在类主体中始终使用。

 

__extends

您会注意到,一旦继承了TypeScript类,它也会生成以下函数:

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 __();
};

 

这里d是指派生类,b是指基类。此功能有两件事:

  1. 将基类的静态成员复制到子类,即 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  2. 设置子类函数的原型,以选择性地在父类上查找成员,proto即有效d.prototype.__proto__ = b.prototype

 

人们很少难于理解1,但许多人却与2纠缠不清。

d.prototype.__proto__ = b.prototype

 

在为许多人辅导之后,我发现以下解释是最简单的。首先,我们将解释from的代码如何__extends等效于simple d.prototype.__proto__ = b.prototype,然后解释为什么这一行本身很重要。

 

要了解所有这些,您需要了解以下内容:

  1. __proto__
  2. prototype
  3. 效果newthis调用的函数内
  4. 效果newprototype__proto__

 

JavaScript中的所有对象都包含一个__proto__成员。在较旧的浏览器中通常无法访问该成员(有时文档将此神奇属性称为[[prototype]])。

 

它有一个目标:如果在查找(例如obj.property)期间未在对象上找到属性,则将其查找到obj.__proto__.property。如果仍未找到它,则obj.__proto__.__proto__.property直到:找到它最新的值.__proto__本身为null。这解释了为什么据说JavaScript支持开箱即用的原型继承

 

在下面的示例中显示了该示例,您可以在chrome控制台或Node.js中运行它:

var foo = {}

// setup on foo as well as foo.__proto__
foo.bar = 123;
foo.__proto__.bar = 456;

console.log(foo.bar); // 123
delete foo.bar; // remove from object
console.log(foo.bar); // 456
delete foo.__proto__.bar; // remove from foo.__proto__
console.log(foo.bar); // undefined

 

很酷,所以您了解__proto__。另一个有用的事实是,functionJavaScript 中的所有都具有一个称为的属性prototype,并且其成员constructor指向该函数。

 

如下所示:

function Foo() { }
console.log(Foo.prototype); // {} i.e. it exists and is not undefined
console.log(Foo.prototype.constructor === Foo); // Has a member called `constructor` pointing back to the function

 

现在让我们看一下on 在被调用函数内部的效果newthis。基本上this,在调用的函数内部将指向将从函数返回的新创建的对象。

 

很容易看出您是否this对函数内部的属性进行了突变:

function Foo() {
    this.bar = 123;
}

// call with the new operator
var newFoo = new Foo();
console.log(newFoo.bar); // 123

现在,你需要知道的唯一的另一件事是调用new一个函数分配prototype的函数来的__proto__是从函数调用返回的新创建的对象的。

 

这是您可以运行以完全理解它的代码:

function Foo() { }

var foo = new Foo();

console.log(foo.__proto__ === Foo.prototype); // True!

 

现在直接看下面的内容__extends。我可以自由地为这些行编号:

 

1  function __() { this.constructor = d; }
2   __.prototype = b.prototype;
3   d.prototype = new __();

 

以相反的方式读取d.prototype = new __()第3行上的此函数意味着d.prototype = {__proto__ : __.prototype}(由于newon prototype和的影响__proto__),将其与__.prototype = b.prototype;您获得的上一行(即第2行)结合起来d.prototype = {__proto__ : b.prototype}

 

但是,等等,我们只想d.prototype.__proto__改变原型并保留旧的d.prototype.constructor。这是第一行(即function __() { this.constructor = d; })的含义所在的位置。在这里,我们将有效地使用它d.prototype = {__proto__ : __.prototype, constructor : d}(因为newon this在被调用函数内部的影响)。所以,既然我们恢复d.prototype.constructor,我们已经真正变异的唯一的事情就是__proto__因此d.prototype.__proto__ = b.prototype

 

d.prototype.__proto__ = b.prototype 意义

 

重要的是,它允许您将成员函数添加到子类并从基类继承其他成员函数。下面的简单示例说明了这一点:

 

function Animal() { }
Animal.prototype.walk = function () { console.log('walk') };

function Bird() { }
Bird.prototype.__proto__ = Animal.prototype;
Bird.prototype.fly = function () { console.log('fly') };

var bird = new Bird();
bird.walk();
bird.fly();

 

基本上bird.fly从被查找bird.__proto__.fly(记住,new使得bird.__proto__Bird.prototype)和bird.walk(一种遗传性构件)将被从查找bird.__proto__.__proto__.walk(如bird.__proto__ == Bird.prototypebird.__proto__.__proto__== Animal.prototype)。

 

翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/classes-emit.md

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值