Подтвердить что ты не робот

Зачем встраивать класс JavaScript в анонимную функцию()?

Я читал о новом JavaScript-подобном языке от Microsoft под названием TypeScript. На игровая площадка (раздел примера) существует простой класс в синтаксисе TypeScript, преобразованный в код JavaScript. Исходя из фона программирования Java, мне было интересно узнать, как OOP выполняется в JavaScript как скомпилированный из TypeScript.

Код TypeScript:

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}   

var greeter = new Greeter("world");

var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
    alert(greeter.greet())
}

document.body.appendChild(button)

И эквивалентный код JavaScript:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
    alert(greeter.greet());
};
document.body.appendChild(button);

Часть TypeScript очень похожа на Java, поэтому я это понимаю. Теперь мой вопрос: почему в JavaScript тело класса Greeter встроено в анонимный вызов function()?

Почему бы не написать это так?

function Greeter(message) {
    this.greeting = message;
}
Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

В чем преимущество/недостаток каждого метода?

4b9b3361

Ответ 1

Ниже вызывается выражение "Вынужденная функция":

(function(){ ... })();

Используется для сохранения глобальной видимости. Хотя в этом случае это не обязательно, поскольку возвращаемое значение присваивается переменной Greeter. Единственный момент, когда этот шаблон полезен, - это когда вы хотите "private" статические члены.

например:.

var Greeter = (function () {
    var foo = 'foo', bar = 'bar'; /* only accessible from function defined
                                     in the local scope ... */

    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

Ответ 2

Помимо очевидных рассуждений о приближении/закрытии. Использование анонимной функции, которая вызывает себя непосредственно, предварительно загружает (интерпретирует) определение класса. Это позволяет оптимизировать JIT-оптимизацию в ходе выполнения. Короче говоря, для более сложных приложений это улучшит производительность.

Ответ 3

Анонимная функция/самозавершение закрытия обычно используется для инкапсуляции области видимости, так что только возвращаемое значение доступно за ее пределами. (или все, что вы прикрепляете к другим объектам, например окну)

Ответ 4

Это разрешено для частных членов. В этом примере все участники являются общедоступными, поэтому ваши две конструкции эквивалентны. Однако, если вы хотите предоставить частным членам, вам нужно скрыть их из области вызова через закрытие. Таким образом, если у вас есть частный член, например:

class Greeter {
    private greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
} 

Вероятно, вы получили бы что-то вроде этого:

var Greeter = (function () {
    var greeting="";
    function Greeter(message) {
        greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + greeting;
    };
    return Greeter;
})();

Приветствующая переменная будет доступна для любой функции, определенной внутри анонимной функции, но невидимой везде.

Ответ 5

Возможно, анонимная функция предотвращает совпадение имен с другими частями кода. Подумайте об этом так, внутри своей анонимной функции вы даже можете объявить переменную с именем "$", чтобы быть тем, что хотите, и в то же время использовать jQuery в других частях вашего кода без конфликтов.

Ответ 6

Закрытие является единственным средством вызова конструкторов с параметрами:

var w = new Greeter("hello")

Существуют и другие методы, но все сложные и с ограничениями и недостатками.