什么是最大的JavaScript陷阱?

我正在计划介绍关于JavaScript的介绍,并且在准备过程中,我想知道新手们陷入的最大缺陷是什么。

我知道在完全理解闭包之前,我已经有了一些小问题,但是JavaScript中的许多奇怪行为并不是我想的更多…

那么,你应该向新秀们指出哪些缺陷?

布尔types转换 。

'' == '0' //false 0 == '' //true 0 == '0' //true false == 'false' //false false == '0' //true false == undefined //false false == null //false null == undefined //true " \t\r\n" == 0 //true 

以及nullundefined之间的区别。 如上表中所列,将nullundefined==进行比较会返回true,但使用===则返回false。 一旦你明白undefined与具有null值的variables有很大的不同,并且undefined值与 undefined不同的东西是不同的,

不要意外地在对象定义文字中留下尾随逗号,否则IE将失败,直到很久以后才会注意到,因为您从不使用IE浏览器进行开发,那么它可能会搞砸了发生的事情。

 var foo = { bar: "bar", baz: "baz", }; 

注意@ JulianR的评论:在数组中,IE不会直接抛出一些语法错误,但是当你尝试使用数组时,会失败,因为添加的逗号使得IE认为数组中有一个元素,值undefined ,实际上是。 所以,如果因为某种原因,数组中的最后一个元素是undefined那么如果你有错误:这是一个逗号。

不可否认,我过去曾经犯过一些这样的错误,为了您的喜悦,这是大胆的:

  • 不知道eval不正确(以及很less的正确使用)
     eval("obj."+prop); 
  • 使用语句
  • 使用parseInt(str, base)而不指定base参数。
  • 在定时器/callback函数中使用this
  • 在定时器中使用类似eval的expression式
     setTimeout("someFunc(myScopedVarWhoops)"); 
  • 思考jQuery是你正在编写的语言的名称
  • 使用框架执行简单的JavaScript任务 – $(1).plus(1)任何人? 😉
  • continue使用,不增加或调整条件variables。
  • 用variables淹没全局名称空间
  • 忘记var或之前for语句。 for (i=0;i<10;i++)
  • 使用混淆器,让它在您的代码上运行
  • 不是一个真正的陷阱,但没有意义 – return condition ? true : false; return condition ? true : false; 而不是return condition;
  • 不评论你的代码 ,确实适用于所有的语言。
  • 使用try...catch...finally语句来捕获错误,而不是使用if语句来检查variables。
  • 愚蠢地试图通过阻止你的网页上的鼠标右键来停止“查看源代码” (我是年轻的* sobs * !)
  • 使用{ 0: "Foo", 1:"Bar", 2:"Foobar" }而不是[ "Foo", "Bar", "Foobar" ]
  • 在用户input上使用parseInt()
     parseInt("1,000") // -> 1, wrong! +"1,000" // -> NaN, correct! 

一些已经提到:

  • 尽可能不使用严格的相等( === )运算符
  • 将事件处理程序设置为函数的返回值而不是对所述函数的引用
  • 不是; 正确地结束语句
  • 在数组中使用for...in循环

睡觉后可能还会想一些:-)

  • 忘记用var声明variables
  • 误解(或不理解)variables的范围和封闭
  • 试图解决框架团队已经解决的讨厌的兼容性问题

+连接string:

 var a = '2'; var b = 3; a * b # 6 a - b # -1 a + b # 23 

JavaScriptstring不是字节串,也不是Unicodestring。 它们是UTF-16string。

例:

 > "♫".length 1 > "𐌈".length 2 > "𐌈".charAt(0) "\uD800" > "𐌈".charAt(1) "\uDF08" > "𐌈" === "\uD800\uDF08" true 

如果上面看起来像垃圾,责怪你的浏览器有错误的Unicode处理(或可能是你的字体,因为没有“老意大利字母”字符)。

对于初学者来说,我所看到的最大困难是理解执行上下文(即什么“这个”意味着什么时候遇到什么地方)以及inheritance的原型系统。

  • 闭包 – 也称为lambda函数 – 注意内存泄漏。
  • 浏览器的差异,在Internet Explorer和至less一个其他浏览器testing是必须的。 通常应避免只能在某些浏览器中工作的function,或在不同浏览器中以不同方式工作的function。 如果这是不可能的浏览器特定的分支更好地完成检测浏览器function,而不是浏览器版本。 这增加了代码在未经testing的浏览器和浏览器中工作的机会。
  • 太习惯于jQuery或Ajax框架抽象,并且不知道底层JavaScript是否足够了解如何解决框架问题。
  • 不知道JavaScript可以用来在一定程度上写OOP代码。 事实上,它可以给你一个非常基本的面向对象的OOP框架。
  • 区分大小写(如果您是VB.NET开发人员)
  • 知识产权保护 – 知道你可以混淆JavaScript,但你放在那里的源代码将是非常容易窃取和逆向工程。 这可能不是一个问题,这取决于你写的客户端应用程序的复杂性。

我想不到了,但我希望这有助于。

  • 使用window.onload = init(); 而不是window.onload = init;
  • 布尔等价(如前所述)
  • 循环内的闭合。
  • 使用for in循环variables来迭代数组。
  • 不使用; 因为它是“可选的”。
  • this (只是…一般:))
  • 不使用var
  • 知道obj.ref === obj["ref"]
  • 创build没有JavaScript的网站
  • 使用JavaScript来完成服务器端应该完成的任务
  • 将框架用于不需要它们的简单任务

原型的整个概念需要一些时间来充分理解,但这里有一些常见的陷阱:

在分配原型对象后忘记重置构造函数属性:

 var Foo() = function () { this.batz = '...'; }; Foo.prototype = new Bar(); Foo.prototype.constructor = Foo; 

如果你忘记了最less的一行, new Foo()会实际执行Bar()

原型的另一个缺陷是迭代对象/数组而不滤除原型的成员:

 for (var i in obj) { if (obj.hasOwnProperty(i)) { //stuff... } } 

额外的条件将跳过从obj的原型inheritance的任何成员。

不是一个真正的编码陷阱,但更多的一般思想:
不要相信你的JavaScript正在做的事情,它可能已经被closures,甚至猴子修补 。 这意味着永远不要依靠客户端validation。 决不。

 typeof null is object >>> var i = 1 + undefined; i; NaN >>> var i = 1 + null; i; 1