typescript 为什么在匿名函数()调用中嵌入 JavaScript 类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12692250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:10:41  来源:igfitidea点击:

Why embed the JavaScript class in an anonymous function() call?

javascripttypescript

提问by AlexStack

I was reading about the new JavaScript-like language from Microsoft called TypeScript. In the playground (example section), there is a simple class in TypeScript syntax converted to JavaScript code. Coming from a Java programming background, it was interesting for me to learn how OOP is done in JavaScript as compiled from TypeScript.

我正在阅读来自 Microsoft 的名为TypeScript的新的类 JavaScript 语言。在操场(示例部分)中,有一个简单的 TypeScript 语法类转换为 JavaScript 代码。来自 Java 编程背景,了解如何在从 TypeScript 编译的 JavaScript 中完成 OOP 对我来说很有趣。

The TypeScript code:

打字稿代码:

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)

And the equivalent JavaScript code:

以及等效的 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);

The Typescript part is very similar to Java so I understand that. Now my question is why in JavaScript the body of the Greeterclass is embedded in a an anonymous function()call?

Typescript 部分与 Java 非常相似,所以我理解这一点。现在我的问题是为什么在 JavaScript 中Greeter类的主体嵌入在匿名function()调用中?

Why not write it like this?

为什么不这样写呢?

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

What is the advantage/disadvantage of each method?

每种方法的优缺点是什么?

采纳答案by xandercoded

The following is called an Immediately Invoked Function Expression:

以下称为立即调用函数表达式

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

It is used to keep the global scope clean. Though, in this case it isn't necessary since the return value is assigned to a variable Greeter. The only time this pattern is useful is when you want "private" staticmembers.

它用于保持全局范围清洁。但是,在这种情况下,没有必要,因为返回值已分配给变量Greeter。只有当您需要“私有”静态成员时,此模式才有用。

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

回答by Mark Porter

This is to allow for private members. In this example, all members are public so your two constructions are equivalent. However, if you want to provide for private members you need to hide them from the calling scope via a closure. Thus if you have a private member like so:

这是为了允许私人成员。在这个例子中,所有成员都是公共的,所以你的两个结构是等价的。但是,如果您想提供私有成员,则需要通过闭包将它们从调用范围中隐藏起来。因此,如果您有这样的私人成员:

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

You would probably get something like this:

你可能会得到这样的东西:

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

The greeting variable will be available to any function defined inside the anonymous function, but invisible everywhere else.

问候变量将可用于匿名函数中定义的任何函数,但在其他任何地方都不可见。

回答by Louis Ricci

Besides the obvious scoping/closure reasoning. Using an anonymous function that invokes itself immediately pre-loads (interprets) the class definition. This allows any JIT optimizations to be front loaded within the execution. In short, for larger more complex applications it will improve performance.

除了明显的范围/结束推理。使用立即调用自身的匿名函数预加载(解释)类定义。这允许在执行中预先加载任何 JIT 优化。简而言之,对于更大更复杂的应用程序,它将提高性能。

回答by Jordan Denison

The anonymous function / self executing closure is usually used to encapsulate scope so that only the returned value is accessible outside of it. (or anything you attach to other objects, like window)

匿名函数/自执行闭包通常用于封装范围,以便只有返回值才能在其外部访问。(或您附加到其他对象的任何东西,例如窗口)

回答by Deleteman

The anonymous function is probably there to prevent name collition with other parts of the code. Think of it this way, inside your anonymous function, you could even declare a variable called "$" to be whatever you want, and at the same time, be using jQuery on other parts of your code without conflict.

匿名函数可能是为了防止与代码的其他部分发生名称冲突。这样想,在您的匿名函数中,您甚至可以将名为“$”的变量声明为您想要的任何变量,同时,在代码的其他部分使用 jQuery 不会发生冲突。

回答by Thinol

The closure is the sole mean to call the constructors with parameters:

闭包是调用带参数的构造函数的唯一方法:

var w = new Greeter("hello")

There are other methods but all complicated and with limitations and drawbacks.

还有其他方法,但都很复杂并且有局限性和缺点。