一、注释:
多行注释格式:最好接近java风格
/*
* 这是一段注释
* 这段注释包含两行,星号对齐,星号后有一个空格为佳
*/
多行注释之前应当有一个空行,且缩进层级和其他描述的代码保持一致。
二、语句表达式
1、所有的块语句都应该使用花括号:
if; for ; while ; do...while... ; try....catch....finally ;
推荐在括号两边各加一个空格,例如:
if ( condition ){
doSomething();
}
- switch语句
倾向于在没有默认行为且写了注释的情况下省略default,例如:
switch(condition){
case "first":
//代码
break;
case "second":
//代码
break;
//没有 default
}
- for循环
break可以直接跳出所有循环;
continue可以跳出本次循环,直接进行下一循环,但是不推荐使用continue ,当使用continue时,JSLint会给出警告,JSHint不会给出警告。
- for-in 循环
用来遍历对象属性,返回属性名,而不是值 ,例如
var prop;
for ( prop in object) {
console.log("Property name is "+ prop );
console.log("Property value is "+ object[prop]);
}
不包含原型的遍历,推荐
var prop;
for ( prop in object) {
if (object.hasOwnProperty(prop)) {
console.log("Property name is "+ prop );
console.log("Property value is "+ object[prop]);
}
}
三、变量、函数和运算符
1、变量声明:提前至函数顶部
2、函数调用间隔:在函数名和左括号之间没有空格
好的写法: doSomething(item); 不好的写法: doSomething (item);
jQuery风格:在左括号之后,和右括号之前都加上空格
doSomething( item );
3、立即调用的函数
声明匿名函数,并将其赋值给变量或属性
Crockford编程规范推荐这样用:
//好的写法
var value = (function(){
//函数体
return {
message: "Hi"
}
});
4、相等
- 强制类型转换: == ;!=
会将非数值类型的变量先转为数值类型,再和数值类型比较。
- 非强制类型转换 === !==
不仅比较值大小是否相同,且比较数据类型是否相同。
- eval()的参数是一个字符串,会将传入的参数当做一段js代码来执行
- 禁止使用原始包装类型,当使用String,Number,或Boolean来创建对象时,JSLint 和JSHint都会给出警告。
四、UI层的松耦合
HTML在下层,CSS和JAVASCRIPT在上层
将CSS从JavaScript中抽离出来,原则上所有的样式信息都应该保持在CSS中,当需要通过JS来修改元素样式的时候,最佳方法是CSS的className,比如:在页面中显示一个对话框,在CSS中的样式定义是像下面这样:
.reveal {
color: red;
left: 10px;
top: 100px;
visibility: visible;
}
然后,在JS中像这样将样式添加至元素。
//好的写法 -- 原生写法
element.className += " reveal";
//好的写法 -- HTML5
element.classList.add("reveal");
//好的写法 -- YUI
Y.one(element).addClass("reveal");
//好的写法 -- Dojo
dojo.addClass(element, "reveal");
任何时刻,CSS中的样式是可以修改的,而不用更新JavaScript,JS不应该直接操作样式,以便保持和CSS的松耦合。
- 将JS从HTML中抽离出来
不好的写法:<button οnclick="doSomething()" id="action-btn"> Click Me </button>
function doSomething() {
//代码
}
var btn = document.getElementById("action-btn");
addListener(btn, "click", doSomething);
使用JQuery的情况下:
$("#action-btn").on("click", doSomething);
- 将HTML从JS中抽离出来
将HTML嵌入到JS中是非常不好的实践,增加了跟踪文本和结构性问题的复杂性。
解决办法:1.从服务器加载;
五、避免使用全局变量
推荐:单全局变量方式,创建自己的命名空间,或采用模块的方式。
六、时间处理
规则:隔离应用逻辑;不要分发事件对象;
var MyApplication = {
handleClick: funtion(even){
//假设事件支持 DOM Level2
event.preventDefault();
event.stopPropagation();
//传入应用逻辑
this.showPopup(event.clientX, event.clientY);
},
showPopup: function(x, y){
var popup = document,getElementById("popup");
popup.style.left = x + "px";
popup.style.top = y + "px";
popup.className = "reveal";
}
};
addEventListener(element, "click",function(event){
MyApplication.handleClick(event);
};
MyApplication.handleClick(event);将X,Y坐标传入MyApplication.showPopup(),代替了之前传入的事件对象,可以清晰的看到MyApplication.showPopup(),所希望传入的参数,并且在测试或代码的任意位置都可以轻易地直接调用这段逻辑。例如
MyApplication.showPopup(10, 10);
MyApplication.handleClick();是事件处理程序,因此它在将数据传入应用逻辑之前调用了event.preventDefault()和 event.stopPropagation(),这清楚地展示了事件处理程序和应用逻辑之间的分工。因为应用逻辑不需要对event产生依赖,进而在很多地方否可以轻松的使用相同的业务逻辑,包括写测试代码。
八、避免空比较
1、检测原始值 五种原始类型:字符串、数字、布尔值、null、undefined。
//检测字符串
if (typeOf name === "String") {
anotherName = name.substr(3);
}
//检测数字
if (typeof count === "number") {
updateCount(count);
}
//检测布尔值
if (typeof found === "boolean" && found) {
message("Found!");
}
//检测 undefined
if (typeof MyApp === "undefined") {
MyApp = {
//其他的代码
}
}
2、检测引用值