54

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

根据我的经验,专家与中级的区别在于能够从各种看似等效的方式中进行选择,以做同样的事情。

那么,当涉及到 JavaScript 时,哪些事情不应该做,为什么

我可以为 Java 找到很多这样的内容,但由于 JavaScript 的典型上下文(在浏览器中)与 Java 非常不同,我很想知道结果如何。

4

10 回答 10

49

语:

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

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

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

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

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

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

  • 参考不存在的undefined常数

设计/部署:

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

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

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

特定于 Ajax:

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

  • 轮询

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

其中许多来自 Addy Osmati 的《学习 JavaScript 设计》一书:https ://www.oreilly.com/library/view/learning-javascript-design/9781449334840/ch06.html

编辑:我一直在想更多!

于 2008-12-18T14:38:54.420 回答
20

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

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

  • 使用类似 Javascript 的内联<body onload="doThis();">
    (不灵活并阻止多个事件侦听器)

  • 使用 'Function()' 构造函数
    (出于同样的原因eval()不好是不好的)

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

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

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

    <evangelism> 当然,不使用 Prototype ;) </evangelism>

于 2008-12-18T18:54:11.393 回答
12

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

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

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

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

最后是部署问题。

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

<plug> 我的博客上有一些客户端优化技巧,涵盖了我上面提到的一些内容,以及更多内容。</plug>

于 2008-12-19T12:00:14.330 回答
9
  • 浏览器检测(而不是测试您要使用的特定方法/字段是否存在)
  • 在大多数情况下使用 alert()

另请参阅 Crockford 的“Javascript: The Good Parts”以了解其他各种要避免的事情。(编辑:警告,他的一些建议有点严格,比如使用“===”而不是“==”所以把它们和任何对你有用的盐一起服用)

于 2008-12-18T14:50:59.107 回答
8

有几件事就在我的头上。当我想到更多时,我会编辑这个列表。

  • 不要污染全局命名空间。而是在对象中组织事物;
  • 不要省略变量的“var”。这会污染全局命名空间,并可能让您在使用其他此类脚本时遇到麻烦。
于 2008-12-18T14:37:53.317 回答
7

任何使用'with'

with (document.forms["mainForm"].elements) {
input1.value = "junk";
input2.value = "垃圾"; }

于 2008-12-18T15:09:04.483 回答
5

任何参考

document.all

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

于 2008-12-18T14:44:27.997 回答
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很好地解释了我从 jQuery 源视频中学到的10 件事

于 2011-03-31T20:51:57.407 回答
4

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

于 2008-12-18T15:03:35.993 回答
0

很少进行有效的缓存:

  • 当您可以使用像Google 的 Libraries API这样的共享 API来加速页面加载时,不要在您的服务器上存储库(jQuery、Prototype、Dojo)的副本
  • 将所有脚本合并并缩小为一个
  • 使用mod_expires为您的所有脚本提供无限的缓存寿命(从不重新下载)
  • 版本化您的 javascript 文件名,以便客户端无需重新加载/重新启动即可进行新的更新(即 myFile_r231.js 或 myFile.js?r=231)
于 2011-03-31T20:38:06.773 回答