gpt4 book ai didi

javascript - JavaScript 的 "new"关键字是否被认为是有害的?

转载 作者:行者123 更新时间:2023-12-04 00:43:42 26 4
gpt4 key购买 nike

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

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

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

最佳答案

Crockford 在推广优秀的 JavaScript 技术方面做了很多工作。他对语言关键要素的固执己见引发了许多有益的讨论。也就是说,有太多的人把每一个“坏”或“有害”的宣言都当作福音,拒绝超越一个人的看法。有时可能会有点令人沮丧。
使用 new 提供的功能与从头开始构建每个对象相比,关键字有几个优点:

  • Prototype inheritance .尽管那些习惯于基于类的 OO 语言的人经常带着怀疑和 mock 的态度看待,但 JavaScript 的 native 继承技术是一种简单且令人惊讶的代码重用方法。和 new关键字是使用它的规范(也是唯一可用的跨平台)方法。
  • 表现。这是 #1 的副作用:如果我想为我创建的每个对象添加 10 个方法,我可以编写一个创建函数,手动将每个方法分配给每个新对象……或者,我可以将它们分配给创建函数的prototype并使用 new剔除新对象。这不仅更快(原型(prototype)上的每个方法都不需要代码),而且避免了为每个方法使用单独的属性来膨胀每个对象。在速度较慢的机器(尤其是速度较慢的 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的优势了无需担心意外误用导致的问题。
    John Resig 在他的 Simple "Class" Instantiation 中详细介绍了这种技术。发布,以及默认情况下将这种行为构建到您的“类”中的方法。绝对值得一读……就像他即将出版的书一样, Secrets of the JavaScript Ninja ,它在 JavaScript 语言的这个和许多其他“有害”功能中发现了隐藏的黄金( with 上的 章节 对于我们这些最初将这个备受诟病的功能视为噱头的人来说尤其具有启发性) .
    通用的健全性检查
    您甚至可以在检查中添加一个断言,如果您对损坏的代码无声工作的想法感到困扰。或者,如 some评论,使用检查引入运行时异常:
    if ( !(this instanceof arguments.callee) ) 
    throw new Error("Constructor called as a function");
    请注意,此代码段能够避免对构造函数名称进行硬编码,因为与前面的示例不同,它不需要实际实例化对象 - 因此,可以将其复制到每个目标函数中而无需修改。
    ES5 带走
    Sean McMillan , stephenbezjrh注意,使用 arguments.callee在 ES5 的 strict mode 中无效.因此,如果您在该上下文中使用上述模式,它将引发错误。
    ES6 和一个完全无害的 newES6 引入 Classes到 JavaScript - 不,不是老派 Crockford 所做的那种怪异的 Java 模仿方式,而是在精神上更像他(和其他人)后来采用的轻量级方式,采用原型(prototype)继承和烘焙通用模式的最佳部分融入语言本身。
    ...其中一部分包括保险箱 new :
    class foo
    {
    constructor()
    {
    // constructor logic that will ONLY be hit
    // if properly constructed via new
    }
    }

    // bad invocation
    foo(); // throws,
    // Uncaught TypeError: class constructors must be invoked with 'new'
    但是,如果您不想使用新糖怎么办?如果您只想使用上面显示的那种安全检查来更新您完美的旧式原型(prototype)代码,以便它们继续在严格模式下工作怎么办?
    好吧,就像 Nick Parsons notes , ES6 也提供了一个方便的检查,形式为 new.target :
    function foo()
    {
    if ( !(new.target) )
    throw new Error("Constructor called as a function");

    // constructor logic follows...
    }
    因此,无论您选择哪种方法,您都可以 - 稍加考虑并保持良好的卫生习惯 - 使用 new没有伤害。

    关于javascript - JavaScript 的 "new"关键字是否被认为是有害的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29733442/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com