JavaScript有哪些反模式? [关闭]

问题描述 投票:49回答:10

我发现,不做的事情比应该做的事情更难学。

[根据我的经验,使专家与中级人员脱颖而出的是从各种看似等效的方式中进行相同选择的能力。

因此,当涉及到JavaScript 您不应该做什么样的事情以及为什么

我能够找到许多针对Java的代码,但是由于JavaScript(在浏览器中)的典型上下文与Java的上下文非常不同,所以我很想知道结果如何。

javascript anti-patterns
10个回答
46
投票

语言:

  • 通过在全局上下文中创建大量足迹来污染名称空间。

  • 以'foo.onclick = myFunc'的形式绑定事件处理程序(不可扩展,应使用attachEvent / addEventListener)。

  • 几乎在所有非JSON上下文中使用eval

  • 几乎每次使用document.write(使用诸如document.createElement之类的DOM方法)]] >>

  • 对象对象原型(BOOM!)

  • 这个很小,但是用'+'进行大量字符串连接(创建数组并将其连接起来效率更高)]]

  • 引用不存在的undefined常量

  • 设计/部署:

    • (通常)不提供noscript支持。

  • 不将您的代码打包到单个资源中

  • 在主体顶部附近放置内联(即主体)脚本(它们加载了块)

  • 特定于Ajax:

    • 不向用户指示请求的开始,结束或错误

  • 轮询

  • 传递和解析XML而不是JSON或HTML(在适当情况下)

  • 其中许多是来自Addy Osmati的《 Learning JavaScript Design》一书:https://www.oreilly.com/library/view/learning-javascript-design/9781449334840/ch06.html

    编辑:我一直在想更多!

除了那些已经提到的...

  • 使用for..in构造遍历数组(迭代数组方法和索引)

  • <body onload="doThis();">使用内联Javascript(僵化并阻止多个事件侦听器)

  • 使用'Function()'构造函数(由于同样的原因,eval()不好,所以不好]

  • 将字符串而不是函数传递给setTimeoutsetInterval((内部也使用eval()

  • 依靠不使用分号的隐式语句(养成不良习惯,并可能导致意外行为)

  • 使用/ * .. * /来屏蔽代码行(可能会干扰正则表达式文字,例如:/* /.*/ */)>

    当然,不使用Prototype;) evangelism>

  • 对我来说最大的是不了解JavaScript编程语言本身。

    • 过度使用对象层次结构并建立非常深的继承链。在大多数情况下,浅层次结构在JS中都能正常工作。
  • 不了解基于原型的面向对象,而是构建大量的脚手架以使JS表现得像传统的OO语言。
  • 当过程/函数编程可以更简洁和有效时,不必要使用OO范式。
  • 然后还有用于浏览器运行时的那些:

    • 没有使用良好建立的事件模式,例如事件委托或观察者模式(发布/订阅)来优化事件处理。
    • 当DOM节点可以在内存中并一次性添加时,进行频繁的DOM更新(如循环中的.appendChild)。 (巨大的性能优势)。
    • 当可以使用本机方法(getElementById,getElementByTagName等)时,过度使用库来选择带有复杂选择器的节点。如今,这已不再是一个小问题,但值得一提。
  • 当您希望第三方脚本与您的脚本位于同一页面时扩展DOM对象(您将最终破坏彼此的代码)。
  • 最后是部署问题。

    • 不缩小文件。
    • Web服务器配置-不压缩文件,不明智地缓存它们。

    我的博客上有client-side optimization tips,涵盖了我上面提到的一些内容,以及更多内容。

    • 浏览器检测(而不是测试您要使用的特定方法/字段是否存在)
  • 在大多数情况下使用alert()
  • 另请参阅Crockford的"Javascript: The Good Parts",以了解其他需要避免的其他事项。 ([edit:

    警告,他在一些建议中有些严格,例如在“ ==”上使用“ ===”,因此请适量食用,以适合您的口味)]

    我头上有几件事。当我想到更多时,将编辑此列表。

    • 不污染全局名称空间。而是组织对象中的事物;
    • 不要为变量省略'var'。这会污染全局名称空间,并可能使您遇到其他此类脚本的麻烦。

    对'with'的任何使用

    with(document.forms [“ mainForm”]。elements){input1.value =“垃圾”;input2.value =“垃圾”;}

    任何参考

    document.all
    

    在您的代码中,除非

    在特殊代码中,仅用于IE克服IE错误。 (咳嗽
    document.getElementById()咳嗽)

    不使用基于社区的框架来执行重复性任务,例如DOM操作,事件处理等。

    创建语句时大括号定位的错误使用

    由于自动插入分号,因此您应始终在语句后加上大括号。

    例如,此:

    function()
    {
        return
        {
            price: 10
        }
    }
    

    与此有很大不同:

    function(){
        return{
            price: 10
        }
    }
    

    因为在第一个示例中,javascript会为您插入一个分号,而实际上您将为此留给您:

    function()
    {
        return;    // oh dear!
        {
            price: 10
        }
    }
    

    将setInterval用于可能长时间运行的任务。

    在需要重复执行某些操作的情况下,应使用setTimeout而不是setInterval。

    如果使用setInterval,但是在下一个计时器计时时,计时器中执行的功能尚未完成,这很糟糕。而是使用setTimeout

    使用以下模式
    function doThisManyTimes(){
        alert("It's happening again!");
    }
    
    (function repeat(){
        doThisManyTimes();
        setTimeout(repeat, 500);
    })();
    

    [Paul Irish在他的10 things I learned from the jQuery source视频中对此做了很好的解释

    很少进行有效缓存:

    • [当您可以使用Google's Libraries API之类的共享API来加速页面加载时,请勿在服务器上存储库的副本(jQuery,Prototype,Dojo)>
    • Combine and minify您可以将所有脚本合并为一个
  • 使用mod_expires赋予所有脚本无限的缓存寿命(永远不要重新下载)
  • 版本您的javascript文件名,以便客户端无需重新加载/重新启动即可进行新的更新(即myFile_r231.js或myFile.js?r = 231)

  • 1
    投票

    很少进行有效缓存:

    • [当您可以使用Google's Libraries API之类的共享API来加速页面加载时,请勿在服务器上存储库的副本(jQuery,Prototype,Dojo)>
    • Combine and minify您可以将所有脚本合并为一个

    19
    投票

    除了那些已经提到的...

    • 使用for..in构造遍历数组(迭代数组方法和索引)


    11
    投票

    对我来说最大的是不了解JavaScript编程语言本身。

    • 过度使用对象层次结构并建立非常深的继承链。在大多数情况下,浅层次结构在JS中都能正常工作。
  • 不了解基于原型的面向对象,而是构建大量的脚手架以使JS表现得像传统的OO语言。

  • 9
    投票
    • 浏览器检测(而不是测试您要使用的特定方法/字段是否存在)
  • 在大多数情况下使用alert()

  • 8
    投票

    我头上有几件事。当我想到更多时,将编辑此列表。

    • 不污染全局名称空间。而是组织对象中的事物;
    • 不要为变量省略'var'。这会污染全局名称空间,并可能使您遇到其他此类脚本的麻烦。

    6
    投票

    对'with'的任何使用

    with(document.forms [“ mainForm”]。elements){input1.value =“垃圾”;input2.value =“垃圾”;}


    5
    投票

    任何参考

    document.all
    

    在您的代码中,除非


    4
    投票

    不使用基于社区的框架来执行重复性任务,例如DOM操作,事件处理等。


    4
    投票

    创建语句时大括号定位的错误使用

    © www.soinside.com 2019 - 2024. All rights reserved.