Страницы

Поиск по вопросам

пятница, 14 июня 2019 г.

Javascript. Что происходит в этом куске кода?

Первый раз вижу такой код.. не пойму, что тут происходит?
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 вот в этом ответе. Там есть чуть больше деталей о самой логике реализации прототипного наследования.

Комментариев нет:

Отправить комментарий