在另一个问题中,一个用户指出使用new关键字是危险的,并提出了一个不使用new的对象创建解决方案。我不相信这是真的,主要是因为我使用过Prototype、Script.aculo.us和其他优秀的JavaScript库,它们都使用new关键字。

尽管如此,昨天我在YUI剧院看了Douglas Crockford的演讲,他说了完全相同的事情,他不再在他的代码中使用new关键字(Crockford谈JavaScript -第三幕:函数终极- 50:23分钟)。

使用new关键字“不好”吗?使用它的优点和缺点是什么?


当前回答

以下是我对支持和反对使用新运算符的两个最有力的论点所做的最简短的总结:

反对新建的理由

Functions designed to be instantiated as objects using the new operator can have disastrous effects if they are incorrectly invoked as normal functions. A function's code in such a case will be executed in the scope where the function is called, instead of in the scope of a local object as intended. This can cause global variables and properties to get overwritten with disastrous consequences. Finally, writing function Func(), and then calling Func.prototype and adding stuff to it so that you can call new Func() to construct your object seems ugly to some programmers, who would rather use another style of object inheritance for architectural and stylistic reasons.

关于这个争论的更多信息,请参阅Douglas Crockford的著作《JavaScript: The Good Parts》。事实上,还是去看看吧。

赞成新

使用新的运算符 原型赋值很快。 那些关于意外的东西 运行一个构造函数 全局名称空间中的代码可以 很容易预防,如果你总是 包含一些代码在您的 要检查的构造函数 看看它们是否被调用 正确,而且,在这种情况下 他们没有,接听电话 如你所愿。

请参阅John Resig的文章,以获得对这种技术的简单解释,以及对他所倡导的继承模型的一般更深入的解释。

其他回答

我认为“新”增加了代码的清晰度。而清晰就是一切。知道有陷阱是好事,但通过避免清晰来避免陷阱似乎不适合我。

另一个新案例是我所说的Pooh Coding。我建议你顺应你所使用的语言,而不是反对它。

这种语言的维护者很有可能会根据他们鼓励使用的习语来优化语言。如果他们在语言中添加了一个新的关键字,他们可能认为在创建新实例时保持清晰是有意义的。

按照语言的意图编写的代码将在每个版本中提高效率。而避免语言关键结构的代码将随着时间的推移而遭受损失。

这远远超出了性能。我数不清我听过(或说过)多少次“他们为什么要这么做?”事实经常证明,在编写代码的时候,有一些“好的”理由。遵循语言之道是你的代码将来不会被嘲笑的最好保证。

我刚刚读了Crockford的书《JavaScript: The Good parts》的一部分。我有一种感觉,他认为凡是咬过他的东西都是有害的:

关于开关故障:

我从不允许开关箱掉下来 进入下一个案例。我曾经发现 我的代码中有一个bug,是由 无意中立刻落空 在做了一次有力的演讲之后 为什么有时候会失败 有用的。(第97页,ISBN 978-0-596-51774-8)

关于++和——:

++(递增)和——(递减) 运营商已经知道 通过鼓励来促成糟糕的代码 过度的诡计多端。他们是第二 只有错误的架构在 启用病毒和其他安全性 威胁。(第122页)

关于新:

如果你忘了说新的 调用构造函数时的前缀 函数,那么这个就不是 绑定到新对象。遗憾的是,这 将被绑定到全局对象,那么 不是扩大你的新对象, 你将在全球范围内大肆宣传 变量。这真的很糟糕。在那里 是否没有编译警告,并且没有 运行时警告。(49页)

还有更多,但我希望你能理解。

对于你的问题,我的回答是:不,它是无害的。但如果你忘记使用它时,你可能会有一些问题。如果你在一个良好的环境中发展,你会注意到这一点。

在ECMAScript的第5版中,支持严格模式。在严格模式下,this不再绑定到全局对象,而是绑定到undefined。

我同意PEZ和一些人的观点。

在我看来,“新”显然是自我描述的对象创建,而Greg Dean所描述的YUI模式完全被模糊了。

有人可能会写var bar = foo;或者var bar = baz();在baz不是对象的地方,创建方法似乎要危险得多。

JavaScript是一种动态语言,有无数种方法可以把其他语言阻止你的事情搞砸。

避免使用像new这样的基本语言特性,因为你可能会搞砸,这有点像在穿过雷区之前脱掉你闪闪发光的新鞋,以防你的鞋被弄脏。

我使用了一种约定,函数名以小写字母开头,而实际上是类定义的“函数”以大写字母开头。结果是一个非常引人注目的视觉线索,“语法”是错误的:

var o = MyClass();  // This is clearly wrong.

最重要的是,良好的命名习惯会有所帮助。毕竟,函数是做事情的,因此它的名字中应该有一个动词,而类代表对象,是没有任何动词的名词和形容词。

var o = chair() // Executing chair is daft.
var o = createChair() // Makes sense.

Stack Overflow的语法着色是如何解释上面的代码的,这很有趣。