Первый раз вижу такой код.. не пойму, что тут происходит?
var DemoAppModel = (function (_super) {
__extends(DemoAppModel, _super);
function DemoAppModel() {
_super.call(this);
}
DemoAppModel.prototype.auth = function () {}
return DemoAppModel;
})(observable.Observable);
exports.DemoAppModel = DemoAppModel;
exports.mainViewModel = new DemoAppModel();
Где про это можно прочитать?
Ответ
TL;DR: Это полифил для реализация наследования в версиях до ES6.
До преобразования транспилятором (скорее всего речь идет о TypeScript) этот код (как верно отметил @Pavel Mayorov) имел вид:
export class DemoAppModel extends observable.Observable {
auth() { }
}
export var mainViewModel = new DemoAppModel();
Давайте разберемся что-здесь происходит строчка за строчкой:
// Создаем IIFE(*1), возвращающую конструктор класса DemoAppModel
// Аргумент "_super" - конструктор родительского класса.
var DemoAppModel = (function (_super) {
// Выставляем правильную цепочку прототипов для вновь созданного
// конструктора(*2).
// Обратите внимание, "DemoAppModel" здесь - это функция определенная
// строчкой ниже, а не функция из предыдущей области видимости(*3).
__extends(DemoAppModel, _super);
// Определяем нашу функцию конструктор.
function DemoAppModel() {
// Вызываем родительский конструктор в контексте вновь созданного
// экземпляра DemoAppModel. Это необходимо для правильной
// инициализации переменных экземпляра, определенных через
// родительский конструктор.
_super.call(this);
}
// Создаем новый метод для экземпляров DemoAppModel, который ничего
// не делает.
DemoAppModel.prototype.auth = function () {}
// Возвращаем созданный конструктор.
return DemoAppModel;
// Вызываем IIFE(*1) передавая конструктор родительского класса в качестве
// аргумента.
})(observable.Observable);
// Экспорт функции конструктора и созданного с его помощью экземпляра
// для использования в других модулях.
exports.DemoAppModel = DemoAppModel;
exports.mainViewModel = new DemoAppModel();
Замечания:
IIEF(Immediately-invoked function expression) - функция, которая вызывается сразу же, как только она определена.
В общем случае, функция __extends имеет вид (без полифила для ES<5):
function __extends(ctor, superCtor) {
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
Что именно здесь происходит несколько выходит за рамки вопроса и требует отдельного дополнительного обсуждения.
В JavaScript мы можем использовать функции до момента их определения благодаря "Поднятию определения".
Некоторое время назад я уже рассказывал, как именно работает прототипное наследование в JavaScript вот в этом ответе. Там есть чуть больше деталей о самой логике реализации прототипного наследования.
Комментариев нет:
Отправить комментарий