【问题标题】:What is the advantage of using this JavaScript coding pattern to define constructor functions?使用这种 JavaScript 编码模式来定义构造函数有什么好处?
【发布时间】:2012-03-07 07:28:27
【问题描述】:

我倾向于用以下方式编写对象构造函数:

function Person(name) {
    this.name = name;
}
Person.prototype.greet = function () {
    alert("Hello! My name is " + this.name + ".");
};

我注意到一些 JavaScript 库和框架添加了一些额外的代码,如下所示:

var Person = (function () {
    function Person(name) {
        this.name = name;
    }
    Person.prototype.greet = function () {
        alert("Hello! My name is " + this.name + ".");
    };
    return Person;
})();

我知道自动执行匿名函数的作用和用途。我目前看不到的是在定义构造函数及其原型时它提供了哪些优势或好处。

编辑#1:

我知道模块模式及其优点,并且在我的编码中经常使用它。我在沟通中的错误并不清楚我的第一个代码示例不应该在全局范围内。我总是将所有外部 JavaScript 文件包装在一个自动执行的匿名函数中,以在代码上强制执行本地范围。

例如:

;(function ( window, undefined ) {
    var p = function (name) {
        this.name;
    };
    p.prototype.greet = function () {
        alert("Hello! My name is " + this.name + ".");
    };
    window.Person = window.Person || p;
})(window);

问题是我已经看到我的第二个代码示例中显示的技术在in这样的匿名函数中使用。

例如:

;(function ( window, undefined ) {
    var p = (function () {
        var q = function (name) {
            this.name = name;
        };
        q.prototype.greet = function () {
            alert("Hello! My name is " + this.name + ".");
        };
        return q;
    })();
    window.Person = window.Person || p;
})(window);

这就是我对这项技术的重要性感到茫然的地方。

【问题讨论】:

  • 在这个具体的例子中,没有区别。我认为对于更复杂的类,这可能很重要,这取决于框架在额外范围内做什么。
  • @Domenic - 你的答案与我希望的答案一致。我想知道是否有人可以对此进行详细说明。

标签: javascript constructor anonymous-function function-prototypes module-pattern


【解决方案1】:

第二种方法,模块模式,更具可移植性。请注意,您可以将 Person 命名为任何您想要的名称。

在第一种方法中,您必须跟踪Person 的每次出现,并注意在将构造函数+原型复制到另一个项目时不要意外删除部分方法。

第二种方法有一个额外的优势:您可以使用本地/临时/一次性变量,这些变量可用于在命名空间上动态定义常量/方法/属性。

【讨论】:

    【解决方案2】:

    它实际上是一个命名空间,不是吗?

    【讨论】:

    • 不,你是对的。这通常是这种模式的用途;通过将所有内容包装在闭包中来避免污染全局命名空间。
    • 不,我想说“命名空间”和“闭包”之间存在区别。当然,window 对象类似于命名空间,您可以使用闭包来填充命名空间,但在这些示例中没有。
    【解决方案3】:

    我更喜欢第一个解决方案,对我来说更少的代码更清晰。

    只有当您经常将代码复制粘贴到其他库时,我才能更好地看到第二种解决方案,但我认为这不是一个很好的理由

    【讨论】:

      【解决方案4】:

      这是我的同事的答案,他不仅对 JavaScript 了如指掌,而且对浏览器中所有各种 JavaScript 引擎的工作原理都了如指掌,他告诉我,这种代码模式是定义对象的一种不必要且过于防御性的方式用于处理允许范围蔓延的某些 JavaScript 解析器(他特别引用了 Opera 版本)中的错误。这确实听起来是一个合理的答案......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-12
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多