什么是最大的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
以及null
和undefined
之间的区别。 如上表中所列,将null
和undefined
与==
进行比较会返回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