使用这种 JavaScript 编码模式来定义构造函数有什么好处?
我倾向于用以下方式编写对象构造函数:
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);
事实是,我已经看到我的第二个代码示例中显示的技术在这样的匿名函数中使用。
例如:
;(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);
这是我对该技术的重要性感到困惑的地方。
I tend to write object constructors in the following way:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
alert("Hello! My name is " + this.name + ".");
};
I've noticed a few JavaScript libraries and frameworks adding some extra code around that like so:
var Person = (function () {
function Person(name) {
this.name = name;
}
Person.prototype.greet = function () {
alert("Hello! My name is " + this.name + ".");
};
return Person;
})();
I know what the self-executing anonymous function does and is used for. What I fail to see at the moment is what advantage or benefit this provides when defining a constructor and its prototype.
EDIT #1:
I know the module pattern and its advantages, and use it fairly often in my coding. My mistake in communication was not being clear that my first code sample is not supposed to be in the global scope. I always wrap all of my external JavaScript files in a self-executing anonymous function to enforce local scope on the code.
For instance:
;(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);
The thing is that I've seen the technique displayed in my second code sample used within such an anonymous function.
For instance:
;(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);
This is where I'm at a loss for the significance of the technique.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
第二种方法,即模块模式,更加可移植。请注意,您可以将
Person
命名为您想要的任何名称。在第一种方法中,您必须跟踪
Person
的每次出现,并在将构造函数+原型复制到另一个项目时小心不要意外删除该方法的一部分。第二种方法有一个额外的优点:您可以使用本地/临时/一次性变量,这些变量可用于动态定义命名空间上的常量/方法/属性。
The second method, the module pattern, is more portable. Notice that you can name
Person
to anything you want.At the first method, you would have to keep track of every occurrence of
Person
, and be careful to not accidentally delete part of the method when copying the constructor+prototype to another project.The second method has an additional advantage: You can use local/temporary/throw-away variables which can be used to dynamically define constants/methods/properties on the namespace.
它实际上是一个名称空间,不是吗?
It's effectively a namespace isn't it?
我更喜欢第一个解决方案,更少的代码对我来说更清晰。
只有当您经常将代码复制粘贴到其他库时,我才能更好地看到第二个解决方案,但我认为这不是一个很好的理由
I preferer first solution, less code more clear for me.
I see the second solution better only if you copy paste often your code to other library, but I don't think this is a good reason
这是我的同事的答案,他不仅对 JavaScript 有着不可思议的了解,还对浏览器中所有各种 JavaScript 引擎的工作原理有着不可思议的了解,他告诉我,这种代码模式是一种不必要的、过度防御性的方式来定义所使用的对象。处理某些 JavaScript 解析器(他特别引用了 Opera 版本)中允许范围蔓延的错误。这确实听起来是一个合理的答案......
This is the answer that my co-worker, who has an uncanny knowledge of not just JavaScript but how all the various JavaScript engines in browsers works, told me that this pattern of code is an unnecessary and overly defensive way to define objects that is used to deal with faults in certain JavaScript parsers (he specifically cited versions of Opera) that allow for scope creep. It certainly sounds like a reasonable answer...