小编典典

JavaScript 的“new”关键字被认为是有害的吗?

all

一位用户指出该new关键字使用起来很危险,并提出了一个未使用的对象创建解决方案new。我不相信这是真的,主要是因为我使用过
Prototype、Scriptaculous 和其他优秀的 JavaScript 库,而且每个人都使用了new关键字。

尽管如此,昨天我在 YUI 剧院观看 Douglas Crockford 的演讲,他说了同样的话,他new不再在代码中使用关键字(Crockford
on JavaScript - Act III: Function the Ultimate -50:23分钟
)。

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


阅读 91

收藏
2022-03-07

共1个答案

小编典典

Crockford 在推广优秀的 JavaScript
技术方面做了很多工作。他对语言关键要素的固执己见引发了许多有益的讨论。也就是说,有太多的人把每一个“坏”或“有害”的宣言都当作福音,拒绝超越一个人的看法。有时可能会有点令人沮丧。

new与从头开始构建每个对象相比,使用关键字提供的功能有几个优点:

  1. 原型继承。尽管那些习惯于基于类的 OO 语言的人经常带着怀疑和嘲笑的态度看待,但 JavaScript 的本机继承技术是一种简单且令人惊讶的代码重用方法。关键字是使用它的new规范(也是唯一可用的跨平台)方法。
  2. 表现。这是 #1 的副作用:如果我想为我创建的每个对象添加 10 个方法,我 可以 编写一个创建函数,手动将每个方法分配给每个新对象……或者,我可以将它们分配给创建函数prototype并用于new剔除新对象。这不仅更快(原型上的每个方法都不需要代码),而且避免了为每个方法使用单独的属性来膨胀每个对象。在速度较慢的机器(尤其是速度较慢的 JS 解释器)上,当创建许多对象时,这可能意味着显着节省时间和内存。

是的,new有一个关键的缺点,其他答案巧妙地描述了:如果您忘记使用它,您的代码将在没有警告的情况下中断。幸运的是,这个缺点很容易缓解 -
只需在函数本身添加一些代码:

function foo()
{
   // if user accidentally omits the new keyword, this will 
   // silently correct the problem...
   if ( !(this instanceof foo) )
      return new foo();

   // constructor logic follows...
}

现在您可以拥有new无​​需担心意外误用引起的问题的优势。你甚至可以在检查中添加一个断言,如果破坏代码默默工作的想法让你感到困扰。或者,正如一些评论的那样,使用检查来引入运行时异常:

if ( !(this instanceof arguments.callee) ) 
   throw new Error("Constructor called as a function");

(请注意,此代码段能够避免对构造函数名称进行硬编码,因为与前面的示例不同,它不需要实际实例化对象 - 因此,可以将其复制到每个目标函数中而无需修改。)

John Resig 在他的简单“类”实例化帖子中详细介绍了这项技术,并在默认情况下将这种行为构建到您的“类”中。绝对值得一读……正如他即将出版的书,JavaScript
Ninja 的秘密
,它在 JavaScript
语言的这个和许多其他“有害”特性中发现了隐藏的黄金(对于我们这些最初不屑一顾的人来说,这一章特别有启发性
with这个备受诟病的功能是一种噱头)。

2022-03-07