简体   繁体   English

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

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

I was reading about the new JavaScript-like language from Microsoft called TypeScript . 我正在阅读微软称为TypeScript的类似JavaScript的新语言。 In the playground (example section) , there is a simple class in TypeScript syntax converted to JavaScript code. playground(示例部分)中 ,TypeScript语法中有一个简单的类转换为JavaScript代码。 Coming from a Java programming background, it was interesting for me to learn how OOP is done in JavaScript as compiled from TypeScript. 来自Java编程背景,我很有兴趣了解如何在使用TypeScript编译的JavaScript中完成OOP。

The TypeScript code: 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)

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. Typescript部分与Java非常相似,所以我理解。 Now my question is why in JavaScript the body of the Greeter class is embedded in a an anonymous function() call? 现在我的问题是为什么在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? 每种方法的优点/缺点是什么?

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 . 但是,在这种情况下,由于将返回值分配给变量Greeter因此不需要。 The only time this pattern is useful is when you want "private" static members. 此模式唯一有用的时间是您想要“私有” 静态成员。

Eg: 例如:

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

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. greeting变量可用于匿名函数内定义的任何函数,但在其他任何地方都不可见。

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. 这允许在执行中预先加载任何JIT优化。 In short, for larger more complex applications it will improve performance. 简而言之,对于更大更复杂的应用程序,它将提高性能。

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) (或任何附加到其他对象的东西,如窗口)

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而不会发生冲突。

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. 还有其他方法,但都很复杂,有局限和缺点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM