0

在发现 TypeScript 之后,我玩弄了在线编译器,生成的 JavaScript 代码让我对函数表达式感到好奇。

一个简单的 TypeScript 类:

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

生成以下 JavaScript 代码:

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

这让我想知道为什么他们选择使用自动执行功能,而更简单的东西可能就足够了。名称与变量相同的内部函数的目的是什么?
为什么他们不使用更简单的东西,例如:

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

甚至:

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


据我所知,在全局范围内使用函数表达式没有任何好处,只有在声明之前无法调用函数的缺点。

4

3 回答 3

2

它有助于继承。它允许他们通过重命名来捕获基类,_super这有助于代码生成,例如:

class Foo{

}

class Bar extends Foo{

}

变成:

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

这也是 JS 中的好习惯。例如,如果您Foo在此示例中继续使用而不是_super并且您要更改基类,您将有一个可以避免的头疼的整个途径。

于 2013-11-15T03:47:40.283 回答
1

您真的不希望能够在其声明执行之前调用一个类。考虑这段代码:

class Person {
    static nameSeparator = ' ';

    public fullName: string;

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

及其生成的形式:

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

您是否希望在指定行之前意外运行的代码以未定义的行为运行(在这种情况下,Person.fullName 是“JohnundefinedSmith”),或者只是失败?

在其他情况下,该类根本不起作用:

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;
    }
}
于 2013-11-15T03:33:49.537 回答
-1

这允许您创建一些私有变量。

在 JS 中:

var Person = (function () {
    var firstName, lastName; //static private vars
    function Person(fName, lName) {
        firstName = fName;
        lastName = lName;
    }
    return Person;
})();
于 2013-11-15T03:18:41.493 回答