为什么这个由Typescript生成的JavaScript构造函数包装了一个立即调用的函数?

时间:2013-08-15 21:07:16

标签: javascript typescript

有人可以向我解释这个'构造函数'定义的优点是什么:

var Tree = (function () {
  function Tree(name) {
    this.name = name;
  }
  return Tree;
})();

而不是

var Tree = function(name) {
   this.name = name;
};

第一个变体是由TypeScript编译器生成的。

3 个答案:

答案 0 :(得分:6)

在TypeScript的情况下,还有额外的闭包来捕获基类

class Animal {
    public run() {
        console.log('running!');
    }
}

class Giraffe extends Animal {
    public run() {
        super.run();
        console.log('... and looking awkward');
    }
}

可发出:

var Animal = (function () {
    function Animal() {
    }
    Animal.prototype.run = function () {
        console.log('running!');
    };
    return Animal;
})();

var Giraffe = (function (_super) {
    __extends(Giraffe, _super);
    function Giraffe() {
        _super.apply(this, arguments);
    }
    Giraffe.prototype.run = function () {
        _super.prototype.run.call(this);
        console.log('... and looking awkward');
    };
    return Giraffe;
})(Animal);

注意使用_super.prototype通过传递给立即调用函数的参数(此处为Animal)来引用基类。如果没有额外的闭包,就无法在不污染全局命名空间的情况下保存该值。

答案 1 :(得分:5)

在这个具体的例子中,没有区别。 如果您想在范围内保留一些变量,可能会有差异:

var Tree = (function () {
  var greeting = "Hello ";
  function Tree(name) {
    this.firstname = greeting + name;
  }
  return Tree;
})();

此外,在这种情况下,无法修改greeting变量(事实上,它是私有的)。

答案 2 :(得分:2)

该函数将被命名,这将在堆栈跟踪和调试工具中产生更多有用的结果。

但是,您可以通过以下方式获得相同的效果:

function Tree(name) {
    this.name = name;
}

如果你已经简化了代码,那么你可能已经删除了一个闭包的使用,该闭包可能创建了类似于Class变量的东西(在函数的所有实例之间共享的一段数据)。