Зачем вставлять класс JavaScript в анонимный вызов функции ()?

Я читал о новом JavaScript-подобном языке от Microsoft под названиемМашинопись, вдетская площадка (пример раздела)в синтаксисе TypeScript есть простой класс, преобразованный в код JavaScript. Исходя из опыта программирования на Java, мне было интересно узнать, как ООП выполняется в 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;
};

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

 user167518702 окт. 2012 г., 16:32
Я думал, что это будет дляprivate участники, но ... добавлениеprivate ничего не меняет.
 I Hate Lazy02 окт. 2012 г., 16:32
Этот код JavaScript не использует конкретно вызываемую анонимную функцию. Вы правы, это может быть удалено.

Ответы на вопрос(6)

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

Решение Вопроса

Следующее называетсяImmediately Invoked Function Expression:

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

Он используется для поддержания глобальной области чистоты. Хотя в этом случае это не является необходимым, поскольку возвращаемое значение присваивается переменнойGreeter, Этот шаблон полезен только тогда, когда вы хотите & quot; приватный & quot;static члены.

E.g.:

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

    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
 02 окт. 2012 г., 18:27
foo а такжеbar будет приватным и статичным в этом случае.

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

 24 апр. 2014 г., 00:22
Не могли бы вы дать ссылку на источник с дополнительной информацией о части JIT?

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

 02 окт. 2012 г., 16:48
Я не понимаю, что вы подразумеваете под этим .... не могли бы вы подробнее остановиться на комментарии?
 02 окт. 2012 г., 16:31
Это присваивает одно и то же имя.

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

var w = new Greeter("hello")

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

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

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

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

 02 окт. 2012 г., 16:39
Нет.var greeting не создан, он используется только для внутреннего использования. Я только что попробовал;)
 02 окт. 2012 г., 16:49
Многие определения каркасов предназначены только для внутренних проверок. Как переменное замедлениеstring или жеprivate функции. Фреймворк проверяет, правильно ли вы его использовали, и создает JavaScript, который не имеет значения, что вы делаете.
 02 окт. 2012 г., 16:45
ну тогда я бы предположил, что есть некоторые скрытые свойства, которые генерируются платформой, которые не должны загрязнять результирующий объект, просто не частные члены
 02 окт. 2012 г., 16:39
Вы бы думали, что получите что-то подобное, но вы этого не делаете. TypeScript применяетprivate модификатор только во время компиляции, так что даже когда вы его используете, он все еще устанавливаетthis.greeting (который, очевидно, вообще не является приватным, но ваш TypeScript не будет компилироваться, если вы попытаетесь получить к нему доступ).

Ваш ответ на вопрос