JavaScript存在哪些反模式?

时间:2008-12-18 14:30:11

标签: javascript anti-patterns

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

根据我的经验,专家与中级人员之间的区别在于能够从各种看似相同的方式中做出相同的选择。

那么,谈到JavaScript 你应该做什么样的事情以及为什么

我能够为Java找到很多这些,但由于JavaScript的典型上下文(在浏览器中)与Java非常不同,我很想看看它是什么。

10 个答案:

答案 0 :(得分:46)

语言:

  • 通过在全局上下文中创建大量变量来进行命名空间污染。

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

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

  • 几乎每次使用document.write(使用像document.createElement这样的DOM方法)

  • 针对Object对象的原型设计(BOOM!)

  • 这是一个很小的一个,但用'+'做大量的字符串连接(创建一个数组并加入它更有效)

  • 参考不存在的undefined常数

设计/部署:

  • (一般情况下)不提供noscript支持。

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

  • 将内联(即正文)脚本放在身体顶部附近(阻止加载)

特定于Ajax:

  • 未指明对用户的请求的开始,结束或错误

  • 轮询

  • 传递和解析XML而不是JSON或HTML(适当时)

编辑:我一直在考虑更多!

答案 1 :(得分:19)

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

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

  • 使用Javascript inline,如<body onload="doThis();">
    (不灵活且可防止多个事件侦听器)

  • 使用'Function()'构造函数
    (由于同样的原因eval()很糟糕)

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

  • 不依赖分号依赖隐式陈述 (拾取的坏习惯,可能导致意外行为)

  • 使用/ * .. * /来阻止代码行
    (可以干扰正则表达式文字,例如:/* /.*/ */

    &LT;传授&GT; 当然,不使用Prototype;) &LT; /传授&GT;

答案 2 :(得分:11)

对我而言最大的不是理解JavaScript编程语言本身。

  • 过度使用对象层次结构并构建非常深的继承链。在大多数情况下,浅层次结构在JS中工作正常。
  • 不了解基于原型的面向对象,而是构建大量的脚手架,使JS的行为与传统的OO语言类似。
  • 当程序/功能编程更简洁有效时,不必使用OO范例。

然后是浏览器运行时的那些:

  • 未使用事件委托或观察者模式(pub / sub)等良好建立的事件模式来优化事件处理。
  • 当DOM节点可以在内存中并一次性附加时,进行频繁的DOM更新(如循环中的.appendChild)。 (巨大的性能优势)。
  • 当可以使用本机方法时,过度使用库来选择具有复杂选择器的节点(getElementById,getElementByTagName等)。现在这个问题变得越来越少,但值得一提。
  • 当您希望第三方脚本与您的页面位于同一页面时扩展DOM对象(最终会破坏彼此的代码)。

最后是部署问题。

  • 不缩小文件。
  • 网络服务器配置 - 不要压缩你的文件,而不是明智地缓存它们。

&LT;塞&GT;我有一些client-side optimization tips,其中涵盖了我上面提到的一些内容,以及更多内容,在我的博客上。&lt; / plug&gt;

答案 3 :(得分:9)

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

另见Crockford的"Javascript: The Good Parts"以避免各种其他事情。 (编辑:警告,他对他的一些建议有点严格,比如使用“===”而不是“==”所以带上任何粒子的盐为你工作)

答案 4 :(得分:8)

一些事情就在我的头顶。当我想到更多时,我会编辑这个列表。

  • 不要污染全局命名空间。相反,组织对象中的东西;
  • 不要为变量省略'var'。这污染了全局命名空间,可能会让你遇到其他类似脚本的麻烦。

答案 5 :(得分:6)

使用'with'

  
    

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

  

答案 6 :(得分:5)

的任何提及
document.all

在您的代码中,除非它在特殊代码中,只是为了克服IE错误。 (咳嗽 document.getElementById()咳嗽

答案 7 :(得分:4)

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

答案 8 :(得分:4)

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

由于自动分号插入,你应该总是在语句后添加一个大括号。

例如:

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解释了这一点

答案 9 :(得分:1)

很少进行有效的缓存:

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