2015-08-25 2 views
4

Следующая машинопись Код:Как работает расширение в TypeScript?

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:

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.

Попытка разработать магию за этой функцией. Я не понимаю, почему мы должны скопировать свойства базового класса в производный класс (т. Е. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];) и создать новый объект с помощью функции __ и подключить прототипы между b, __, d и экземпляр __.

Какова причина всего этого?

+0

Возможно, для поддержки будущего класса? –

ответ

0

До тех пор, пока поддержка ECMAScript для классов не станет родной, функция extends выполняет наследование ожидаемого поведения наследования.

Если вы привыкли к обычным прототипным наследованиям JavaScript, вам будет интересно, почему он не просто выполняет часть __.prototype = b.prototype;. Если это так, вам будет интересно узнать, что добавление for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; означает, что статические члены также будут скопированы. Например ...

class BaseClassWithConstructor { 
    private _id: number; 
    constructor(id: number) { 
     this._id = id; 
    } 

    static doIt() { 
     alert('Done it'); 
    } 
} 

class DerivedClassWithConstructor extends BaseClassWithConstructor { 
    private _name: string; 
    constructor(id: number, name: string) { 
     this._name = name; 
     super(id); 
    } 
} 

DerivedClassWithConstructor.doIt(); 
0

сгенерированный код Javascript может быть разделен на две части:

for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];

для «наследуемых» статические свойства базового класса. На самом деле в новейшей версии типа сценария, эта строка кода была замещена

extendStatics(d, b);

где определение extendStatics является:

var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };

Единственное отличие состоит в том, что в новой версии , манипулирование [[prototype]] используется, если связанное поведение поддерживается браузерами, в противном случае - отказ от старой практики, то есть копирование каждого принадлежащего свойства из базового класса в производный класс.


И как для

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

Это действительно немного фантазер способ установки prototype из d на новый экземпляр b. Но вместо прямого назначения new b(...) в d.instance используется конструктор dummy __, поскольку для установки прототипа нам не нужен конструктор b, и с помощью фиктивной функции нам не нужно передавать аргументы к конструктору. См. this Ответ.

Смежные вопросы