1.区块 如果循环和判断的代码体只有一行,JavaScript允许该区块(block)省略大括号 if (a) b(); c(); 上面代码的原意可能是下面这样 if (a) { b(); c(); } 但是,实际效果却是下面这样 if (a) { b(); } c(); 因此,总是使用大括号表示区块
2.圆括号 在JavaScript中有两种作用,一种表示函数的调用,另一种表示表达式的组合 // 圆括号表示函数的调用 console.log('abc');
// 圆括号表示表达式的组合 (1 + 2) * 3 表示函数调用时,函数名与左括号之间没有空格。
表示函数定义时,函数名与左括号之间没有空格。
其他情况时,前面位置的语法元素与左括号之间,都有一个空格。 按照上面的规则,下面的写法都是不规范 foo (bar) return(a+b); if(a === 0) {...} function foo (b) {...} function(x) {...} 上面代码的最后一行是一个匿名函数,function是语法关键字,不是函数名,所以与左括号之间应该要有一个空格
3.行尾的分号
for和while循环 for ( ; ; ) { } // 没有分号
while (true) { } // 没有分号 需要注意的是do...while循环是有分号的 do { a--; } while(a > 0); // 分号不能省略
分支语句:if,switch,try if (true) { } // 没有分号
switch () { } // 没有分号
try { } catch { } // 没有分号
函数的声明语句 function f() { } // 没有分号 但是函数表达式仍然要使用分号 var f = function f() { };
4.全局变量 JavaScript最大的语法缺点,可能就是全局变量对于任何一个代码块,都是可读可写。这对代码的模块化和重复使用,非常不利。
因此,避免使用全局变量。如果不得不使用,用大写字母表示变量名,比如UPPER_CASE
变量声明 JavaScript会自动将变量声明”提升”(hoist)到代码块(block)的头部 if (!o) { var o = {}; }
// 等同于
var o; if (!o) { o = {}; } 为了避免可能出现的问题,最好把变量声明都放在代码块的头部 for (var i = 0; i < 10; i++) { // ... }
// 写成
var i; for (i = 0; i < 10; i++) { // ... } 另外,所有函数都应该在使用之前定义,函数内部的变量声明,都应该放在函数的头部
5.new命令 JavaScript使用new命令,从构造函数生成一个新对象 示例: var o = new myObject(); 上面这种做法的问题是,一旦你忘了加上new,myObject()内部的this关键字就会指向全局对象,导致所有绑定在this上面的变量,都变成全局变量。
因此,建议使用Object.create()命令,替代new命令。如果不得不使用new,为了防止出错,最好在视觉上把构造函数与其他函数区分开来。比如,构造函数的函数名,采用首字母大写(InitialCap),其他函数名一律首字母小写
with语句 with可以减少代码的书写,但是会造成混淆 with (o) { foo = bar; } 上面的代码,可以有四种运行结果 o.foo = bar; o.foo = o.bar; foo = bar; foo = o.bar; 这四种结果都可能发生,取决于不同的变量是否有定义。因此,不要使用with语句
相等和严格相等 JavaScript有两个表示”相等”的运算符:”相等”(==)和”严格相等”(===)。
因为”相等”运算符会自动转换变量类型,造成很多意想不到的情况: 0 == ''// true 1 == true // true 2 == true // false 0 == '0' // true false == 'false' // false false == '0' // true ' \t\r\n ' == 0 // true 因此,不要使用“相等”(==)运算符,只使用“严格相等”(===)运算符
语句的合并 a = b; if (a) { // ... } 有些人喜欢写成下面这样 if (a = b) { // ... } 虽然语句少了一行,但是可读性大打折扣,而且会造成误读,让别人误解这行代码的意思是下面这样 if (a === b){ // ... } 建议不要将不同目的的语句,合并成一行
自增和自减运算符 自增(++)和自减(--)运算符,放在变量的前面或后面,返回的值不一样,很容易发生错误。事实上,所有的++运算符都可以用+= 1代替 ++x // 等同于 x += 1; 改用+= 1,代码变得更清晰了。有一个很可笑的例子,某个JavaScript函数库的源代码中出现了下面的片段 ++x; ++x; 这个程序员忘了,还有更简单、更合理的写法 x += 2; 建议自增(++)和自减(--)运算符尽量使用+=和-=代替
switch…case结构 switch...case结构要求,在每一个case的最后一行必须是break语句,否则会接着运行下一个case。这样不仅容易忘记,还会造成代码的冗长。
而且,switch...case不使用大括号,不利于代码形式的统一。此外,这种结构类似于goto语句,容易造成程序流程的混乱,使得代码结构混乱不堪,不符合面向对象编程的原则 function doAction(action) { switch (action) { case 'hack': return 'hack'; break; case 'slash': return 'slash'; break; case 'run': return 'run'; break; default: throw new Error('Invalid action.'); } } 上面的代码建议改写成对象结构 function doAction(action) { var actions = { 'hack': function () { return 'hack'; }, 'slash': function () { return 'slash'; }, 'run': function () { return 'run'; } };
if (typeof actions[action] !== 'function') { throw new Error('Invalid action.'); }
return actions[action](); } 建议避免使用switch...case结构,用对象结构代替