谈谈Javascript那些操蛋的事(一)?
1. 永远不要写function _name(){…}的形式,要养成var _name=function(){}的习惯。
“Javascript中函数是头等公民”,意味着引擎对函数语句的优先处理,这样会导致你的程序很混乱,不仅如此,而且不同的浏览器引擎在处理函数语句的一些操作时,比如重写、apply调用、eval生成等等存在很大差异,如果你不想碰上这些潜在的危险,请养成良好的习惯,记住“Javascript中函数语句是头等公民”,永远不要写函数语句,要换成函数表达式或函数字面量,这样更能体现Javascript函数式编程风格---Lambda表达式。这个源自Scheme语言中函数可以当值赋值给变量的思想在Javascript中大放光彩,而且影响着Python、C++、C#、Java,看看Anders的代码,老赵的代码,原来大师是这样做的、信徒都是这样模仿的。呵呵,对于函数表达式(或函数字面量)我是好话说尽,道理讲绝,用不用随你了
2.一定要养成K&R风格。
无论你信不信,高手的代码都是K&R风格,实话实说,我本人是非常讨厌K&R风格,这是个编程风格问题,没有潜在的风险。如果真是如此,我大可不必如此鼓吹,事实上,形如
return
{
}
引擎会在return后自动插入一个分号,后果可想而知
这时候如果养成这样的习惯
return{
}
刚才那种潜在的风险就消除了。呵呵,好像可以少打一个换行符,为你节省些时间
3. 坚决不要遗漏“;”
在一些特定情况下你遗漏一个“;”不会出现风险,你的程序是正常的。但请你不要侥幸,当你洋洋洒洒上千行JS代码进行压缩时,你会发现总运行不起来,也许“;”就是这个罪魁祸首。呵呵,该加上“;”时一定要加上,这浪费不了你多长时间,不加上也节省不了你多长时间(但有时后果会很严重!)
4. 一定要记住这六大败类。
NaN 0 null “” undefined false
不仅如此,还要懂得如何判定,当你考虑一个传入的参数时,这六大败类你是否都考虑了。当你完成一个完整无误、健壮的程序时,你偶然间遇到一个憋足的程序员,这个憋足的程序员又偶然间遇到憋足的IE,更绝的是又恰好遇到这个百年不遇的憋足属性,忽然间程序就这样崩溃了。你百思不得其解,最后费了九牛二虎之力终于把这个bug找出来,你会说“fuck,我少考虑了一种情况”。呵呵,Javascript程序员的嘴能不脏吗?
5. 要慎用递归调用
有的人说递归简洁、通俗易懂,而递归在不可读懂的代码中也发挥着重要作用。在Javascript中该怎么办?我建议最好不要用,除非在安全的前提下,递归特别容易解决问题时你可以尝试使用。一般而言,各种允许递归的语言把递归转化成循环处理,而Javscript中没这项优化,它直接当做函数调用处理的。函数嵌套调用要考虑中断处的现场记录与恢复,比相同功能的指令代码要耗时一些,更大的问题是引擎对嵌套调用的深度有所限制。当你遇到一个憋足的DOM树时,你用递归处理可能会使程序崩溃。
呵呵,递归是简洁的,但在Javascript中是耗时的,并存在一定风险,用不用随缘
6. 要牢记这些“站着茅厕不拉屎”的保留关键字
在进行Javascript语义API设计时,注意!不要和这些保留字争名子,就算争过了,兼容性也会让你死的难看。呵呵,的确,那些保留字是那么简洁、通俗、漂亮,但是你敢用吗?
7. 谨慎对待DOM的一切
Javascript是一门允许重写的语言,但不同的引擎在一些特殊场合都做了不同的限定,所以在进行故意重写时,你首先问问你重写的了吗?兼容性如何?在进行一些语义API设计时,要避免和DOM的属性名雷同。呵呵,总之,对待DOM属性名字要小心为甚!
8. 勤加“()”
Javascript有一个优点就是:你可以使用“||”和“&&”进行并联和串联求值,可以用“?:”简化条件语句,比如
(e.offsetX||e.layerX)+x; (a+b)||c;a=b+((c.s>d)?1:0);
(a&&a.b&&a.b.c)+(c.s||c.y) …
注意一定不要忘记加上“()”,在涉及“||”,“&&”,“?:”的运算符问题时,即使有些可以不加“()”,也要加上“()”,这是一个习惯问题,好的习惯可以让你从根本上杜绝忘记加“()”的可能性。呵呵,总之,不要认为可以不加“()”就不加“()”,突然间有一天某个时刻可以加“()”但你却不留神忘记加“()”时,你想找到错误都是困难的。
9. 谨慎对待“||”
使用“||”进行并联求值运算是Javascript的一大预言特色,例如
e.x=_e.offsetX||_e.layerX
这时你考虑到_e.offsetX为0的情况没有?虽然有时不会出现问题,但大多数类似这样的并联运算得到的结果都是有风险的。呵呵,消灭此风险的方法就是对“||”运算要考虑周到!
10. 杜绝“==”,“!=”运算符
你是在进行比值吗?那么用“===”,“!==” ,而“==”,“!=”浏览器都说不清,你干吗还趟这趟浑水
11.谨记这个特例 NaN!==NaN,(NaN===NaN)为false
在“===”运算符上,NaN是一个特例,可见,不能过于相信(a===a)的结果!
12. 深思熟虑的对待嵌套定义函数问题。
这个问题说成闭包(cloure)更专业一些,什么是闭包?感觉周爱民的叙述恰如其分-----运行时创建的函数实例。闭包是Javascript中的瑞士军刀就像指针之于C语言。
首先,闭包在Javascript中具有很高的技巧性,例如以下形式
var _o=(function(){
var p1,p2;//…
//…
return {