简体   繁体   English

全局范围的函数表达式

[英]Function expressions on global scope

After discovering TypeScript I've played around with the online compiler and the resulting JavaScript code made me wonder about function expressions. 在发现了TypeScript之后,我使用了在线编译器,并且生成的JavaScript代码让我对函数表达式感到疑惑。

A simple TypeScript class: 一个简单的TypeScript类:

class Person {
    firstName: String = "John";
    lastName: String = "Doe";
}

Results in the following JavaScript code: 结果在以下JavaScript代码中:

var Person = (function () {
    function Person() {
        this.firstName = "John";
        this.lastName = "Doe";
    }
    return Person;
})();

That made me wonder why they chose to go with self-executing function, when something simpler might have sufficed. 这让我想知道为什么他们选择使用自动执行功能,当更简单的东西可能已经足够时。 What is the purpose of an inner function with a name identical to the variable? 内部函数的名称与变量名称相同的目的是什么?
And why didn't they go with something simpler, such as: 为什么他们没有更简单的东西,例如:

var Person = function() {
    this.firstName = "John";
    this.lastName = "Doe";
};

Or even: 甚至:

function Person() {
    this.firstName = "John";
    this.lastName = "Doe";
}


As far as I can tell using function expressions on a global scope offers no advantages, only the disadvantage of not being able to call the function before it was declared. 据我所知,在全局范围内使用函数表达式没有任何优点,只有在声明函数之前无法调用函数的缺点。

It helps with inheritance. 它有助于继承。 It allows them to capture the base class with a rename to _super which helps with code generation eg: 它允许它们通过重命名为_super捕获基类,这有助于代码生成,例如:

class Foo{

}

class Bar extends Foo{

}

becomes : 成为:

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var Foo = (function () {
    function Foo() {
    }
    return Foo;
})();

var Bar = (function (_super) {
    __extends(Bar, _super);
    function Bar() {
        _super.apply(this, arguments);
    }
    return Bar;
})(Foo); // Notice base class is captured here

This is good practice in JS as well. 这也是JS的好习惯。 For example, if you kept using Foo in this example instead of _super and you were to change the base class you would have a whole avenue of headaches which can be avoided. 例如,如果您在此示例中继续使用Foo而不是_super并且您要更改基类,则可能会有一个令人头疼的问题,这是可以避免的。

You really don't want to be able to invoke a class before its declaration has executed. 你真的不希望能够在声明执行之前调用一个类。 Consider this code: 考虑以下代码:

class Person {
    static nameSeparator = ' ';

    public fullName: string;

    constructor(public firstName, public lastName) {
        this.fullName = firstName + Person.nameSeparator + lastName;
    }
}

And its generated form: 它的生成形式:

var Person = (function () {
    function Person(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.fullName = firstName + Person.nameSeparator + lastName;
    }
    Person.nameSeparator = ' '; // <-- Important!
    return Person;
})();

Do you want code that accidently runs before the indicated line to run with undefined behavior (in this case, Person.fullName is "JohnundefinedSmith"), or just fail? 您是否希望在指定的行之前意外运行的代码以未定义的行为运行(在这种情况下,Person.fullName是“JohnundefinedSmith”),或者只是失败?

In other cases, the class simply won't work at all: 在其他情况下,该课程根本不起作用:

class Person {
    constructor(public firstName, public lastName) {
        // Will fail until Person.prototype.getFullName gets set
        console.log('New person, name = ' + this.getFullName());
    }

    getFullName() {
        return this.firstName + " " + this.lastName;
    }
}

This allows for you to make some private variables. 这允许您创建一些私有变量。

In JS: 在JS中:

var Person = (function () {
    var firstName, lastName; //static private vars
    function Person(fName, lName) {
        firstName = fName;
        lastName = lName;
    }
    return Person;
})();

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

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