The first time I see this code .. I do not understand what is happening here?

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

Where can you read about it?

  • This is the transpiled code of some framework, the implementation of the model, where did you find this code? - ThisMan
  • This is from some kind of plug-in to nativescript or node.js - LS2010

3 answers 3

TL; DR: This is a polyfill for implementing inheritance in versions prior to ES6.


Prior to conversion by the transpiler (most likely it is a TypeScript ), this code (as rightly noted by @Pavel Mayorov ) had the form:

 export class DemoAppModel extends observable.Observable { auth() { } } export var mainViewModel = new DemoAppModel(); 

Let's see what happens here line by line:

 // Создаем 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(); 

Remarks:

  1. IIEF (Immediately-invoked function expression) is a function that is called as soon as it is defined.
  2. In general, the __extends function has the form (no polyfil for ES <5):

      function __extends(ctor, superCtor) { ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; 

    What exactly happens here is somewhat beyond the scope of the question and requires a separate additional discussion.

  3. In JavaScript, we can use functions up to the moment of their definition due to " Raising Definition ".

Some time ago I told you exactly how prototype inheritance in JavaScript works in this answer . There is a little more detail about the very logic of prototype inheritance implementation.

    This is the code generated by the TypeScript compiler. Before compiling it was like this:

     export class DemoAppModel extends observable.Observable { auth() { } } export var mainViewModel = new DemoAppModel(); 

    No magic, just create a heir class of another with one empty method and an object of this class.

      The usual class of some plug-in ala Babel (it converts the syntax es5-es6-es7 into code that should be supported in older browsers). Read about es5 classes . Immediately see the similarity of the implementation. At first a class was created, then inheritance was done, then a constructor was called that inherits everything from the parent. And then they created a new auth method.

      • Babel does not generate such code. This is a typescript compiler tried. - Pavel Mayorov
      • @Pavel I therefore said "some kind of plugin ala", I can not know exactly whose code. - DimenSi