JS编写规范

3. JavaScript规范

/**********************等级说明***********************/
/*  1.阻断:执行发生严重错误导致中断,阻碍后续程序的执行  */
/*  2.严重:语法错误导致执行出错                      */
/*  3.主要:影响到性能等                             */
/*  4.次要:可能影响到性能等                          */
/*  5.建议:优化效率性能等                            */
/*  6.图标表示支持sonar检测                          */    
/**********************等级说明***********************/

3.1 js性能优化

3.1.01 js代码要写在js文件中,在html的最末尾的位置引入(主要)

规范明细

99%的js代码应该写在外部的javascript文件中,在html文档标签之前引入以提高页面性能。

正确示例


    
        </span>这是示范页面<span class="hljs-variable">
        
        
    
    
        
... ... /*****************JS文件放置在标签之前位置*******************/ /*****************JS文件放置在标签之前位置*******************/
好处
  • 便于代码管理
  • html代码结构规范
  • 不影响页面的渲染速度

3.1.02 不要使用document.write()方式(主要)

规范明细

不要使用document.write(),可以使用console.log()或者document.createElement()代替

错误示例
document.write("...")

3.1.03 对象声明直接使用 {}(主要)

规范明细

对象声明直接使用 {},开始的大括号放在声明的同一行,不要使用Object对象实例化方式,因为浏览器对常用的数据类型做了优化处理。

正确示例
var book = {
    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
}
错误示例
var book = new Object();
book.title = "Maintainable JavaScript";
book.author = "Nicholas C. Zakas";

3.1.04 数组(Array)使用[]声明(主要)

规范明细

数组(Array)使用[]声明,不要使用Array对象实例化方式

正确示例
var colors = [ "red", "green", "blue" ];
var numbers = [ 1, 2, 3, 4 ];   
错误示例
var colors = new Array("red", "green", "blue");
var numbers = new Array(1, 2, 3, 4);

3.1.05 不要使用原始的包装数据类型(数字、字符串、布尔、数组、对象)申明变量(主要)

规范明细

不要使用原始的包装数据类型申明变量

正确示例
var str = "This is a string object."; // 字符串
var num = 0; // 数字
var boolean = false; // 布尔
var numbers = [ 1, 2, 3, 4 ];    // 数组
var book = { // 对象
    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
}
错误示例
var str = new String("This is a string object."); // 字符串
var num = new Number(0); // 数字
var boolean = new Boolean(); // 布尔
var numbers = new Array(1, 2, 3, 4); // 数组
var book = new Object(); // 对象
book.title = "Maintainable JavaScript";
book.author = "Nicholas C. Zakas";

3.1.06 不要使用 eval()语句(主要)

规范明细

不要使用 eval()语句,因为它存在安全隐患,导致脚本注入攻击,并且在不同的浏览器引擎下还有效率上的差异

正确示例
(function(){
  var i,t=new Date,o=[];
  for(i=0;i<1E7;i++)o[i]=i;
  console.log(new Date-t);
})();
错误示例
eval(
  "var i,t=new Date,o=[];"+
  "for(i=0;i<1E7;i++)o[i]=i;"+
  "console.log(new Date-t);"
);

3.1.07 不要使用with语句(主要)

规范明细

不要使用with语句,该语句在'strict'模式下会出现问题。此外,使用with访问并操作对象属性的时候,如果修改不属于该对象里面的属性时,它会把操作作用域从对象内部扩展到全局域,以致可能更改对象外部申明的变量值,因此是不安全的。

正确示例
var x = 'a';

var foo = {
  y: 1
}

foo.y = 4;
foo.x = 3;

print(foo.x + " " + x); // 显示: 3 a
错误示例
var x = 'a';

var foo = {
  y: 1
}

with (foo) {  // 错误的使用方式
  y = 4;  // 更新 foo.y的值
  x = 3;  // 这里没有为foo对象新增x属性; 而是更新了外部作用域定义的变量x的值
}
print(foo.x + " " + x); // 显示: undefined 3

3.1.08 不要在循环里面进行DOM操作。(主要)

规范明细

避免在循环里面进行Dom操作。

正确示例
var htmlString = "";

for(var i =0; i
    htmlString += html;
}

$(“.class”).append(htmlString);
错误示例
for(var i =0; i<length;i++){
    $(“.class”).append(html);
}

3.1.09 对于多个同性质同辈节点,避免逐个进行事件绑定。而应该利用冒泡原理,将事件委托给父节点。(主要)

规范明细

对于多个同性质同辈节点,避免逐个进行事件绑定。而应该利用冒泡原理,将事件委托给父节点。

正确示例
$("table").on("click","td",function(){
    ...
})
错误示例
$("td").on("click",function(){
    ...
})

3.1.10 事件委托要接近事件触发节点,避免将所有事件冒泡委托给body节点。(主要)

规范明细

事件委托要接近事件触发节点,避免将所有事件冒泡委托给body节点。

正确示例
$("table").on("click","td",function(){
    ...
})
错误示例
$("body").on("click","td",function(){
    ...
})

3.1.11 通常能用CSS实现的效果要避免使用JS来实现。CSS性能比JS要高。(次要)

规范明细

通常能用CSS实现的效果要避免使用JS来实现。CSS性能比JS要高。


3.1.12 JS要避免直接写在页面中,加快页面加载速度。(主要)

规范明细

JS要避免直接写在页面中,加快页面加载速度。页面最多允许20行JS代码


3.1.13 在开发中,简单的操作能用原生js实现的方式,就不要用三方的插件或者库实现(次要)

规范明细

在开发中,简单的操作能用原生js实现的方式,就不要用三方的插件或者库实现。因为原生的方式执行效率高很多


3.1.14 进行JS合并压缩的,部署之前要进行压缩合并(主要)

规范明细

能够进行JS合并压缩的,部署之前要进行压缩合并。其一是为了减少请求HTTP请求数,提高性能;其二是为了对源码进行加密,降低被COPY的可能性。


3.1.15 在项目满足条件的情况下,使用最新的jQuery版本。(建议)

规范明细

jQuery的版本更新很快,我们应该总是使用最新的版本。因为新版本会改进性能,还有很多新功能。


3.1.16 在使用jQuery时,需要用缓存的方式,避免重复产生过多的jQuery对象。(次要)

规范明细

在使用jQuery时,需要用缓存的方式,避免重复产生过多的jQuery对象。

正确示例
var cached = $('#top'); 
cached.find('p.classA'); 
cached.find('p.classB'); 
错误示例
$('#top').find('p.classA'); 
$('#top').find('p.classB'); 

3.1.17 使用jQuery时进行多重操作,采用其链式写法(次要)

规范明细

使用jQuery时进行多重操作,采用其链式写法

正确示例
$('class').find('h3').eq(2).html('Hello'); 

3.1.18 在js操作DOM的过程中,要避免频繁改动DOM结构,可以先使用字符串方式组装html代码,再插到DOM结构中去(主要)

规范明细

在js操作DOM的过程中,要避免频繁改动DOM结构,可以先使用字符串方式组装html代码,再插到DOM结构中去

正确示例
var html = '<div id="d1"><span id="s1">span><span id="s2">span>div>'; 
$(body).append(html); 
错误示例
var d1 = $('<div id="d1">div>'); 
$(body).append(d1); 
var s1 = '<span id="s1">span>';
d1.append(s1); 
var s2 = '<span id="s2">span>';
d1.append(s2); 

3.1.19 使用$.data(elem,key,value)的方式绑定数据(次要)

规范明细

使用$.data(elem,key,value)的方式绑定数据。因为elem.data()方法是定义在jQuery函数的prototype对象上面的,而$.data()方法是定义jQuery函数上面的,调用的时候不从复杂的jQuery对象上调用,所以速度快得多。

正确示例
$.data(elem,key,value)
错误示例
var elem = $('#elem'); 
elem.data(key,value); 

3.2 js命名规范

3.2.01 所有的布尔值的命名以'is','can','has','should','must'等状态词开头(主要)

规范明细

所有的布尔值的命名以'is','can','has','should','must'等状态词开头

正确示例
var isValid = truecanExcute = false, hasDone = false, 
    shouldHold = true, mustDo = false;

3.2.02 变量名和方法名要合乎逻辑,容易阅读者被理解(主要)

规范明细

变量名和方法名要合乎逻辑

正确示例
var popUpWindowForAd;
错误示例
var myWindow

3.2.03 不要手动来压缩代码(for循环中的条件变量i除外),变量应该足够长且有意义(主要)

规范明细

不要手动来压缩代码(for循环中的条件变量i除外),变量应该足够长且有意义

正确示例
var blackCatSergeant;
错误示例
var bcs;

3.2.04 变量使用驼峰命名法(camel case),使用名词结构(主要)

规范明细

以首字母小写单词开头,后续单词首字母均使用大写,使用名词结构

正确示例
var thisIsMyName;
错误示例
var hello;

3.2.05 方法使用驼峰命名法,使用动宾结构(主要)

规范明细

以首字母小写单词开头,后续单词首字母均使用大写,使用动宾结构

正确示例
function getName() {
    ...
}
错误示例
function hello() {
    ...
}

3.2.06 常量全部使用大写字母,字母之间使用下划线进行连接(主要)

规范明细

常量全部使用大写字母,字母之间使用下划线进行连接,取名要明确表明此常量代表的意义

正确示例
var MAX_COUNT = 10;
var URL = "http://www.nczonline.net/";
错误示例
var maxCount = 10;

3.2.07 构造函数名使用帕斯卡命名法(主要)

规范明细

所有单词均以大写字母开头

正确示例
function Person(name) {
    this.name = name;
}

Person.prototype.sayName = function() {
    alert(this.name);
};

var me = new Person("Nicholas");

3.2.08 数字申明的变量的命名要体现出该变量是数字,不使用八进制声明数值,不省略小数点前后数字以免造成歧义。(严重)

规范明细

数字申明变量的命名要体现出该变量是数字,不使用八进制声明数值,不省略小数点前后数字以免造成歧义。

正确示例
var count = 10; 
var price = 10.0;
var price = 10.00;  
//科学计数法
var num = 1e23;
//十六进制
var num = 0xA2;
错误示例
var temp = 10;
var price = 10.;
var price = .1;
// 八进制
var num = 010;

3.2.09 不要使用js关键字作为申明的变量或者方法名称,如‘eval’,‘arguments’等(严重)

规范明细

不要使用js关键字作为申明的变量或者方法名称,常用的js关键字:

eval break arguments delete function return typeof  
case do if switch var  
catch else in this void  
continue false instanceof throw while  
debugger finally new true with  
default for null try    
正确示例
result = 17;
args++;
++result;
var obj = { set p(arg) { } };
var result;
try { } catch (args) { }
function x(arg) { }
function args() { } 
var y = function fun() { }; 
var f = new Function("args", "return 17;");

function fun() {
  if (arguments.length == 0) {
    // do something
  }
}
错误示例
eval = 17; // 非法
arguments++; // 非法
++eval; // 非法
var obj = { set p(arguments) { } }; // 非法
var eval; // 非法
try { } catch (arguments) { } // 非法
function x(eval) { } // 非法
function arguments() { } // 非法
var y = function eval() { }; // 非法
var f = new Function("arguments", "return 17;"); // 非法

function fun() {
  if (arguments.length == 0) { // 非法
    // do something
  }
}

3.2.10 将来可能成为js关键字(ECMAScript标准定义)的不能作为变量或者方法名称申明(严重)

规范明细

将来可能成为js关键字(ECMAScript标准定义)的不能作为变量或者方法名称申明,未来可能使用的关键字:

abstract double goto native static  
boolean enum implements package super  
byte export import private synchronized  
char extends int protected throws  
class final interface public transient  
const float long short volatile  
await exports let yield
正确示例
dbl = 17.00;
sht++;
++sht;
错误示例
double = 17; // 非法
short++; // 非法
++short; // 非法

3.2.11 方法参数命名必须是唯一的(严重)

规范明细

方法参数命名必须是唯一的

正确示例
function compute(a, b, c) {  
    ...
}
错误示例
function compute(a, a, c) { 
    ...
}

3.2.12 对象属性的命名必须是唯一不能重复的(严重)

规范明细

对象属性的命名必须是唯一不能重复的

正确示例
var data = {
  "key": "value",
  "1": "value",
  "key2": "value",
  'key3': "value",
  key4: "value",
  \u006bey5: "value",
  "\u006bey6": "value",
  "\x6bey7": "value",
  1b: "value"
}
错误示例
var data = {
  "key": "value",
  "1": "value",
  "key": "value", // 重复的 "key"
  'key': "value", // 重复的 "key"
  key: "value", // 重复的 "key"
  \u006bey: "value", // 重复的 "key"
  "\u006bey": "value", // 重复的 "key"
  "\x6bey": "value", // 重复的 "key"
  1: "value" // 重复的 "1"
}

3.2.13 变量需要在被使用前申明(主要)

规范明细

变量需要在被使用前申明

正确示例
var x = 1;

function fun() {
    print(x);
    if (something) {
        x = 42;
    }
}

fun(); // "1"
错误示例
var x = 1;

function fun(){
    alert(x); 
    if(something) {
        var x = 42; 
    }
}

fun(); // "undefined" 而不是 "1"

3.2.14 在同一个作用域下面,不能用相同的名称命名方法和变量(主要)

规范明细

在同一个作用域下面,不能用相同的名称命名方法和变量

正确示例
var fun = function () {
}
错误示例
var fun;
function fun() {
}

3.2.15 变量命名不要覆盖其他的变量,即不要重名(主要)

规范明细

变量命名不要覆盖其他的变量,即不要重名

正确示例
var a = 'foo';
var b = 'bar';

function f(e) {
  var g = "event";
}
错误示例
var a = 'foo';
var a = 'bar'; // 覆盖

function f(e) {
  var e = "event"; // 覆盖
}

3.3 js注释规范

3.3.01 申明的变量(除for循环里面的循环次数控制变量)、方法(包括匿名方法)、对象,对象属性、插件、API、代码块(for循环,if...else...)等都需要有注释来解释(主要)

规范明细

申明的变量(除for循环里面的循环次数控制变量)、方法(包括匿名方法)、对象,对象属性、插件、api、代码块(for循环,if...else...)等都需要有注释来解释。

正确示例
// 这是一个计数器
var count = 10;
错误示例
var count = 10;

3.3.02 单行注释或多行注释之前空一行(主要)

规范明细

单行注释或多行注释之前空一行

正确示例
function aFun() { 

    // 注释...
    ......  
}

3.3.03 单行注释//后空一格(次要)

规范明细

单行注释//后空一格

正确示例
// Single-line comment  
错误示例
//Single-line comment

3.3.04 注释单独一行,注释前空一行,与下一行代码保持相同的缩进。在某行代码后添加行注释,需在代码后空一个4个空格缩进,字符长度不要超过最大字符数(120字符)。(主要)

规范明细

注释单独一行(注释前空一行),说明下一行或一段代码的用意,通常与下一行代码保持相同的缩进。在某行代码后添加行注释,需在代码后空一个tab缩进,这种情形下此行的字符长度不要超过最大字符,如果超过请使用上述风格。

正确示例
if (condition) {

    // if you made it here, then all security checks passed
    allowed();
}

// if (condition) {
//     doSomething();
//     thenDoSomethingElse();
// }
错误示例
if (condition) {
    // if you made it here, then all security checks passed
    allowed();
}

var result = something + somethingElse;// somethingElse will never be null

3.3.05 多行注释以/*开始,以*/结束(主要)

规范明细

多行注释以/*开始,以*/结束

正确示例
/*
* Yet another comment.
* Also goes to a second line.
*/

if (condition) {

    /* 
     * if you made it here, 
     * then all security checks passed
     */
    allowed();
}
错误示例
if (condition) {
/* 
 * if you made it here, 
 * then all security checks passed
 */
    allowed();
}

3.3.06 不要使用HTML注释方式(主要)

规范明细

不要使用HTML注释方式

错误示例


3.3.07 注释语句不要跟在代码同一行后面,要在代码行上一行位置(次要)

规范明细

注释语句不要跟在代码同一行后面,要在代码行上一行位置

正确示例
// 在这个位置评论比较好
var a2 = b + c;
错误示例
var a1 = b + c; // 在这个位置评论不合适

3.4 js代码格式化规范

3.4.01 方法、对象、循环等开始花括号{要跟在方法、对象、循环等起始行的最后面,不要另起一行写(主要)

规范明细

方法、对象、循环等开始花括号{要跟在方法、对象、循环起始行的最后面,不要另起一行书写,不要与结束花括号}保持在同一列。

正确示例
function getData() {
    return {
        title: "Maintainable JavaScript",
        author: "Nicholas C. Zakas"
    }
}
错误示例
function getData() 
{
    return 
    {
        title: "Maintainable JavaScript",
        author: "Nicholas C. Zakas"
    }
}

3.4.02 使用 分号; 结束代码语句(主要)

规范明细

使用 ; 结束代码语句,不能用换行来结束

正确示例
var name = "Nicholas";
function sayName() {
    alert(name);
}   
错误示例
var name = "Nicholas"
function sayName() {
    alert(name)
}   

3.4.03 每行代码的长度不超过120字符,含空格字符(主要)

规范明细

一行代码过长影响可读性,虽然有些编辑器可以进行自动wrap,但代码也会出现长短差距太大的情况,在读代码理解逻辑时就会很不方便。所以请控制你的每一行代码在120个字符以内(包括空格,并非每行代码都要去数有多少字母,写到一个很长的语句的时候控制一下在120个字母左右换行。


3.4.03 同一行方法调用或者表达式换行时,一定要在一个运算符或标点后进行换行(主要)

规范明细

同一行方法调用或者表达式换行时,一定要在一个运算符或标点后进行换行

正确示例
if (isLeapYear && isFebruary && day == 29 && itsYourBirthday &&
        noPlans) {
    waitAnotherFourYears();
}

错误示例

callAFunction(document, element, window, "some string value", true, 123
    , navigator);

3.4.04 同一行方法调用或者表达式,换行后的另一行缩进8个空格(主要)

规范明细

同一行方法调用或者表达式,换行后的另一行缩进8个空格

正确示例
callAFunction(document, element, window, "some string value", true, 123,
        navigator);
错误示例
callAFunction(document, element, window, "some string value", true, 123,
    navigator);

3.4.05 表达式赋值语句换行,第二行要与等号后面的第一个变量对齐(主要)

规范明细

表达式赋值语句换行,第二行要与等号后面的第一个变量对齐

正确示例
var result = something + anotherThing + yetAnotherThing + somethingElse +
             anotherSomethingElse;

3.4.06 每个方法之间空一行(主要)

规范明细

每个方法之间空一行

正确示例
function aFun() {
    ...
}

function bFun() {
    ...
}

3.4.07 在方法的局部变量声明和方法的语句之间空一行(次要)

规范明细

在方法的局部变量声明和方法的语句之间空一行

正确示例
function aFun() {
    var a = ...;
    var b = ...;

    ...
}

3.4.08 运算符前后添加空格(主要)

规范明细

运算符前后添加空格

正确示例
var found = (values[i] === item);
错误示例
var found=(values[i]===item);

3.4.09 圆括号内挨着圆括号的地方不添加空格(主要)

规范明细

圆括号内挨着圆括号的地方不添加空格

正确示例
var found = (values[i] === item);
错误示例
var found = ( values[i] === item );

3.4.10 字符串申明统一使用双引号,如果字符串长度过长,请换行并使用“+”号进行字符串连接(建议)

规范明细

字符串申明统一使用双引号,如果字符串长度过长,请使用“+”号进行字符串连接

正确示例
var longString = "Here's a story of a man " +
    "named Brady.";
错误示例
var longString = "Here's a story of a man named Brady.";

3.4.11 对象所有属性缩进4个空格,第一个属性上面空一行(次要)

规范明细

对象所有属性缩进4个空格,第一个属性上面空一行;

正确示例
var book = {

    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
};

3.4.12 所有属性的值都要对应一个没有引号的属性名,属性名后紧跟一个冒号(不加空格),冒号后加一个空格跟属性的值(主要)

规范明细

所有属性的值都要对应一个没有引号的属性名,属性名后紧跟一个冒号(不加空格),冒号后加一个空格跟属性的值

正确示例
var book = {

    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
};

3.4.13 如果这个属性是方法,他的上下跟着不是方法的属性,上下均要空一行;一组相关的属性后可适当插入一个空行,增加可读性(建议)

规范明细

如果这个属性是方法,他的上下跟着不是方法的属性,上下均要空一行;一组相关的属性后可适当插入一个空行,增加可读性

正确示例
var object = {

    key1: value1,
    key2: value2,

    func: function(){
        // do something
    },

    key3: value3
};  

3.4.14 结束的大括号应该独占一行(主要)

规范明细

结束的大括号应该独占一行

正确示例
var book = {

    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
};

3.4.15 一个对象字面量作为一个参数传入方法中,开始花括号{与调用的方法名同行,属性按键值对方式,单独一行,结束花括号}单独一行(主要)

规范明细

一个对象字面量作为一个参数传入方法中,开始花括号{与调用的方法名同行,属性按键值对方式,单独一行,结束花括号}单独一行

正确示例
doSomething({
    key1: value1,
    key2: value2
}); 

3.4.16 一个逻辑代码块之前空一行(建议)

规范明细

一个逻辑代码块之前空一行

正确示例
function aFun() { 

    if (s.hasOwnProperty(p)) {

        if (merge && type == 'object') {
            Y.mix(r[p], s[p]);
        } else if (ov || !(p in r)) {
            r[p] = s[p];
        }
    }
}

3.4.17 对于多层嵌套的if语句,要进行合并(主要)

规范明细

一个逻辑代码块之前空一行

正确示例
if (x != null && x === 2) {
    ... 
}
错误示例
if (x != null) {
    if (x === 2) {
        // ...
    }
}

3.4.18 js文件行数不要太长,最大行数为1000行(主要)

规范明细

js文件行数不要太长,最大行数为1000行


3.4.19 js方法行数不要太长,最大行数为100行(主要)

规范明细

js方法行数不要太长,最大行数为100行


3.4.20 一行的结尾处不要使用空格字符(主要)

规范明细

一行的结尾处不要使用空格字符,因为这是垃圾代码,增加代码合并时候的冲突


3.4.21 不要使用已经申明名称的方法表达式进行赋值操作(主要)

规范明细

不要使用已经申明名称的方法表达式进行赋值操作

正确示例
fun = function(){};
错误示例
f = function fun(){};

3.4.22 循环或者嵌套的代码块内部不能是空的,没有代码逻辑(主要)

规范明细

循环或者嵌套的代码块内部不能是空的,没有代码逻辑

正确示例
for (var i = 0; i < length; i++) {//some code here}
错误示例
for (var i = 0; i < length; i++) {}

3.4.23 只有while, do, for语句才能使用标记(主要)

规范明细

只有while, do, for语句才能使用标记

正确示例
myLabel:for (i = 0; i < 10; i++) {
    doSomething();
    if(i === 8){
        break myLabel;
    }
}

3.4.24 当for循环缺省了初始计数和递增表达式,要使用while循环代替(次要)

规范明细

for循环缺省了初始计数和递增表达式,要使用while语句代替

正确示例
while (condition) { /*...*/ }
错误示例
for (;condition;) { /*...*/ }

3.4.25 控制流申明if, for, while, switch, try不要嵌套太多层,最多3曾(次要)

规范明细

控制流申明if, for, while, switch, try不要嵌套太多层

错误示例
if (condition1) {                  // 第一层
    /* ... */
    if (condition2) {                // 第二层
        /* ... */
        for(int i = 0; i < 10; i++) {  // 第三层
            /* ... */
            if (condition4) {            // 第四层已不合适
                if (condition5) {          // 第五层已经达到极限了
                    /* ... */
                }
                return;
            }
        }
    }
}

3.4.26 字面量布尔值不能使用在条件表达式里面(次要)

规范明细

字面量布尔值不能使用在条件表达式里面

正确示例
if (booleanVariable) { /* ... */ }
if (!booleanVariable) { /* ... */ }
if (booleanVariable) { /* ... */ }
doSomething(true);
错误示例
if (booleanVariable == true) { /* ... */ }
if (booleanVariable != true) { /* ... */ }
if (booleanVariable || false) { /* ... */ }
doSomething(!false);

3.4.27 在if...else...语句块里面,如果存在返回值是布尔类型的,直接返回if条件的表达式(次要)

规范明细

if...else...语句块里面,如果存在返回值是布尔类型的,直接返回if条件的表达式

正确示例
return expression; 
return !!expression;
错误示例
if (expression) {  
    return true;
} else {
    return false;
}

3.4.28 不要使用制表符(次要)

规范明细

不要使用制表符


3.4.29 strict模式需要谨慎使用(建议)

规范明细

strict模式需要谨慎使用

错误示例
function strict() {
    'use strict';
}

3.4.30 代码块中TODO标记的地方要被处理掉(建议)

规范明细

strict模式需要谨慎使用

错误示例
function doSomething() {
    // TODO
}

3.4.31 常量和配置变量应该放在文件顶部(主要)

规范明细

常量和配置变量(比如:动画播放时间)应该放在文件顶部


3.4.32 当某段代码逻辑存在重复出现的情况,或者在某个作用域下面存在超过8个方法的时候,需要将代码抽象成对象的方式编写,便于二次使用,也避免不必要的代码重复,使代码更具可读性和高效性。(主要)

规范明细

当某段代码逻辑存在重复出现的情况,或者在某个作用域下面存在超过8个方法的时候,需要将代码抽象成对象的方式编写,便于二次使用,也避免不必要的代码重复,使代码更具可读性和高效性。

正确示例
var arithmetic = {
    add: function(a,b){
        return a+b;
    },
    minus: function(a,b){
        return a-b;
    }
    ...
};
错误示例
function add(a,b){
    return a+b;
}

function minus(a,b){
    return a-b;
}

3.4.33 当实现某个方法需要使用大量参数的时候,要将该功能封装成一个对象,以配置方式传入参数,而不是写在方法参数里面,方法的最大参数长度为7(主要)

规范明细

当实现某个方法需要使用大量参数的时候,要将该功能封装成一个对象,已配置方式传入参数,而不是写在方法参数里面方法的最大参数长度为7。

正确示例
var option = {
    url: "",
    height: "",
    width: "",
    ...
};

function Window(option){
    this.option = option;
    ...
}

var window = new Window(option);
错误示例
function setWindow(url,height,width...){
    ...
}

3.4.34 使用面向对象的方式组织js代码(建议)

规范明细

使用面向对象的方式组织你的js代码,参考: Object Literal/Singleton in Module Pattern或者 Object with constructors或者Javascript 面向对象编程.

正确示例
var Cat = {
    name: '',
    color: ''
}
错误示例
var name = "", color = "";

3.5 js代码防错(陷阱)规范

3.5.01 不要进行浏览器嗅探方式判断浏览器客户端版本等信息,请使用特性检测,同时避免使用三方非特性检测方式判断浏览器客户端(主要)

规范明细

不要进行浏览器嗅探方式判断浏览器客户端版本等信息,请使用特性检测,同时避免使用三方非特性检测方式判断浏览器客户端,以免判断不准确

错误示例
ie=!!window.VBArray
ie678=('a-b'.split(/(~)/))[1]=="b"
ie678=0.9.toFixed(0)=="0"
iphone=/iphone/i.test(navigator.userAgent);
$.browser == ...

3.5.02 避免申明全局变量,防止全局空间命名冲突污染(主要)

规范明细

避免申明全局变量,防止全局空间命名冲突污染


3.5.03 不要用null来判断方法的参数有没有提供,不要用null来判断未初始化的变量(严重)

规范明细

不要用null来判断方法的参数有没有提供,不要用null来判断未初始化的变量

错误示例
//判断未初始化的变量
var person;
if (person != null) {
    doSomething();
}

// 判断值有没有传递
function doSomething(arg1, arg2, arg3, arg4) {
    if (arg4 != null) {
        doSomethingElse();
    }
}

3.5.04 不要省略if for while do...while try...catch...finally语句大括号(严重)

规范明细

不要省略if for while do...while try...catch...finally语句大括号

正确示例
if (condition) {
    doSomething();
}
错误示例
if(condition)
    doSomething();

3.5.05 变量定义在变量声明时进行初始化,未初始化的变量放在声明语句的最后(主要)

规范明细

变量定义在变量声明时进行初始化,未初始化的变量放在声明语句的最后。

正确示例
function doSomethingWithItems(items) {
    var value = 10,
    result = value + 10
    i, len;
    for(i=0, len=items.length; i < len; i++) {
        doSomething(items[i]);
    }
}   

错误示例

function doSomething() {
    var result;
    var value;
    result = 10 + value;
    value = 10;
    return result;
}

3.5.06 比较运算使用 ===!== , 不要使用 ==!= 避免类型转换时产生的错误(主要)

规范明细

比较运算使用 ===!== , 不要使用 ==!= 避免类型转换时产生的错误。

正确示例
var same = (a === b);
错误示例
var same = (a == b);

3.5.07 三目运算符用来进行条件性的赋值,不要用来当做简写的 if 语句使用(主要)

规范明细

三目运算符用来进行条件性的赋值,不要用来当做简写的 if 语句使用。

正确示例
var value = condition ? value1 : value2;

错误示例

condition ? doSomething() : doSomethingElse();

3.5.08 使用闭包或者命名空间避免全局空间污染(严重)

规范明细

将一个js文件中的全部代码置于一个匿名函数调用中,或者使用命名空间划分,可以避免命名空间污染

正确示例
//闭包方式
(function (){
    var someVar = null;
    // some code
}());

//命名空间方式
var school = {};
school = {};
school.students = {};
(function(students) {
    // ..... 这里省略了代码 ......

    students.Subject = Subject;
    students.Grade = Grade;
})(school.students);

3.5.09 不要使用“,”逗号来结束语句(阻断)

规范明细

不要使用“,”逗号来结束语句

正确示例
var settings = {
    'foo'  : oof,
    'bar' : rab
};
错误示例
var settings = {
    'foo'  : oof,
    'bar' : rab,
};

3.5.10 switch语句不能包含非case语句(严重)

规范明细

switch语句不能包含非case语句

正确示例
switch (day) {
    case MONDAY:
    case TUESDAY:
    case WEDNESDAY:
        doSomething();
        break;
    ...
}
错误示例
switch (day) {
  case MONDAY:
  case TUESDAY:
  WEDNESDAY:   // 取代 "case WEDNESDAY"
    doSomething();
    break;
  ...
}

3.5.11 switch语句需要以default语句结束(主要)

规范明细

switch语句需要以default结束

正确示例
switch (param) {
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
    default:
        error();
        break;
}
错误示例
switch (param) {  
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
}
//缺少 default 语句

3.5.12 switch语句中每个case(未使用return语句的)需要以break语句结束(主要)

规范明细

switch语句中每个case(未使用return语句的)需要以break语句结束

正确示例
switch (param) {
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
    default:
        error();
        break;
}
错误示例
switch (param) {  
    case 0:
        doSomething();
    case 1:
        doSomethingElse();
        break;
}
//缺少 default 语句

3.5.13 switch语句使用时至少要有3个case语句(包括最后的default语句)(次要)

规范明细

switch语句使用时至少要有3个case语句(包括最后的default语句)

正确示例
switch (param) {
    case 0:
        doSomething();
        break;
    case 1:
        doSomethingElse();
        break;
    default:
        error();
        break;
}
错误示例
//一下的语句可以使用if...else...语句或者if...if...语句
switch (param) {  
    case 0:
        doSomething();
        break;
    default :
        doSomethingElse();
        break;
}

3.5.14 方法体作为参数使用时,要保持与申明的方法在同一行(严重)

规范明细

方法体作为参数使用时,要保持与申明的方法在同一行,不能另起一行,以免造成错误或者歧义

正确示例
svar fn = function () {
   //...
}(function () { // 在同一行
   //...
})();
错误示例
var fn = function () {
   //...
}

(function () { // 未在同一行
   //...
})();

3.5.15 对于对象属性使用for ... in循环时,需要通过hasOwnProperty方法过滤非自身属性(继承而来的属性)(主要)

规范明细

对于对象属性使用for ... in循环时,需要通过hasOwnProperty方法过滤非自身属性(继承而来的属性)

正确示例
for (name in object) {
    if (object.hasOwnProperty(name)) {
        doSomething(name);
    }
}
错误示例
for (name in object) {
    doSomething(name);  // 未过滤掉非自身属性
}

3.5.16 赋值语句不能作为参数或者条件传递(主要)

规范明细

赋值语句不能作为参数或者条件传递

正确示例
i = 42;
doSomething(i);   
doSomething(i == 42);  
if((i = something)<=100)
错误示例
doSomething(i = 42);
if(i = 42)

3.5.17 不要使用位运算符:<<, >>, >>>, ~, &, |(主要)

规范明细

不要使用位运算符:<<, >>, >>>, ~, &, |,因为js的位运算效率不如其他如C等语言,并且在WEB应用里面鲜有这种使用场景。

正确示例
if (a && b) { ... }
var oppositeSigns = false;
if ( (x < 0 && y > 0) || (x > 0 && y < 0) ) {
   oppositeSigns = true;
}
错误示例
if (a & b) { ... } //  & 使用错误
var oppositeSigns = ((x ^ y) < 0); //  有比这更清晰的方式验证

3.5.18 不要使用逗号运算符,但排除特例(主要)

规范明细

不要使用逗号运算符,但排除特例

正确示例
a +=  2;
i = a + b;
错误示例
i = a += 2, a + b; 
特例
for(i = 0, j = 5; i < 6; i++, j++) { ... }

3.5.19 构造函数不要单纯在未申明实例的情况下使用(主要)

规范明细

构造函数不要单纯在未申明实例的情况下使用,因为这时new创建的实例不能在任何地方被使用。

正确示例
var something = new MyConstructor();
错误示例
new MyConstructor(); 

3.5.20 不要在循环体内部定义方法(主要)

规范明细

不要在循环内部创建方法,因为在循环体内部定义的方法只会有一个实例被定义,唯一改变的是方法的参数。

错误示例
var funs = [];
for (var i = 0; i < 13; i++) {
    funs[i] = function() { 
        return i;
    };
}
print(funs[0]()); // 13 而不是 0
print(funs[1]()); // 13 而不是 1
print(funs[2]()); // 13 而不是 2
print(funs[3]()); // 13 而不是 3 

3.5.21 不要定义重复名称的方法(主要)

规范明细

不要定义重复名称的方法,因为前面定义的会被后面定义的覆盖掉

正确示例
fun(); // prints "foo"

function fun() {
  print("foo");
}

fun(); // prints "foo"
错误示例
fun(); // "bar"

// 第一次申明的方法
function fun() {
  print("foo");
}

fun(); //  "bar"

// 新定义同名的方法,覆盖之前的方法
function fun() {
  print("bar");
}

fun(); // "bar"

3.5.22 跳转语句后面不要接其他语句(主要)

规范明细

跳转语句后面不要接其他语句,因为之后的语句不会被执行到。

正确示例
function(a) {
    var i = 10;
    return i + a;
}
错误示例
function(a) {
    var i = 10;
    return i + a;
    i++;
}

3.5.23 一个循环体内部不要使用多个break或者continue关键字(主要)

规范明细

一个循环体内部不要使用多个break或者continue关键字

错误示例
for (var i = 1; i <= 10; i++) { 
    if (i % 2 == 0) {
        continue;
    }

    if (i % 3 == 0) {
        continue;
    }

    alert("i = " + i);
}

3.5.24 方法中未被使用的参数要被移除(主要)

规范明细

方法中未被使用的参数要被移除

正确示例
function doSomething( b) {
    return compute(b);
}
错误示例
function doSomething(a, b) { // "a" 未被使用
    return compute(b);
}

3.5.25 未被使用的变量要被删除(主要)

规范明细

未被使用的变量要被删除

正确示例
function numberOfMinutes(hours) {
    return hours * 60;
}
错误示例
function numberOfMinutes(hours) {
    var seconds = 0;   // seconds 未被使用
    return hours * 60;
}

3.5.26 无效的if...else...要被移除(主要)

规范明细

无效的if...else...要被移除

正确示例
doSomething();

doThirdThing();
错误示例
if (true) { 
  doSomething();
}
...
if (false) { 
  doSomethingElse();
}

if (!options || options === true) { doThirdThing(); }

3.6 用户体验及安全性规范

3.6.01 生产环境下不要使用alert(...)方式提示信息(主要)

规范明细

生产环境下不要使用alert(...)方式提示信息,因为这种方式对用户体验不好,并且会阻碍后续程序的执行,还可能把敏感信息暴露给攻击者。可以使用自定义弹出框提示或者其他方式提示。开发环境下可以使用


3.6.02 生产环境下不要使用debug语句(主要)

规范明细

生产环境下不要使用debug语句,因为容易在出现异常情况下给用户提示其无法理解的内容,也容易被攻击。

错误示例
for (i = 1; i<5; i++) {
    // Print i to the Output window.
    Debug.write("loop index is " + i);
    // Wait for user to resume.
    debugger;
}

你可能感兴趣的:(JS编写规范)