var HTML_ENTITY = {};
// 常用参数
var loadingModules = {};
// 常量
var HTML_ENTITY = {};
// 类
function TextNode(options) {
}
var TargetState = {
READING: 1,
READED: 2,
APPLIED: 3,
READY: 4
};
function Engine(options) {
}
function getStyle(element) {
}
var isReady = false;
var hasMoreCommands = false;
var loadingData = ajax.get('url');
loadingData.then(callback);
单行注释 【强制】 必须独占一行。// 后跟一个空格,缩进与下一行被注释说明的代码一致。
多行注释 【建议】 避免使用 /.../ 这样的多行注释。有多行注释内容时,使用多个单行注释。
文档化注释 【强制】 为了便于代码阅读和自文档化,以下内容必须包含以 /*.../ 形式的块注释中。
类型定义 【强制】 类型定义都是以{开始, 以}结束。
文件注释
/**
* @file Describe the file
* @author author-name(mail-name@domain.com)
* author-name2(mail-name2@domain.com)
*/
/**
* 类描述
*
* @class
* @extends Developer
*/
var Fronteer = function () {
Developer.call(this);
/**
* 属性描述
*
* @type {string}
* @private
*/
this._level = 'T12';
// constructor body
};
util.inherits(Fronteer, Developer);
/**
* 方法描述
*
* @private
* @return {string} 返回值描述
*/
Fronteer.prototype._getLevel = function () {
};
/**
* 函数描述
*
* @param {string} p1 参数1的说明
* @param {string} p2 参数2的说明,比较长
* 那就换行了.
* @param {number=} p3 参数3的说明(可选)
* @return {Object} 返回值描述
*/
function foo(p1, p2, p3) {
var p3 = p3 || 10;
return {
p1: p1,
p2: p2,
p3: p3
};
}
// good
if (age === 30) { }
// bad
if (age == 30) { }
// 字符串为空
// good
if (!name) { }
// bad
if (name === '') { }
// 字符串非空
// good
if (name) { }
// bad
if (name !== '') { }
// 数组非空
// good
if (collection.length) { }
// bad
if (collection.length > 0) { }
// 布尔不成立
// good
if (!notTrue) { }
// bad
if (notTrue === false) { }
// null 或 undefined
// good
if (noValue == null) { }
// bad
if (noValue === null || typeof noValue === 'undefined') { }
// good
function clicker() {
// ......
}
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
addListener(element, 'click', clicker);
}
// bad
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
addListener(element, 'click', function () {});
}
// good
var width = wrap.offsetWidth + 'px';
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
element.style.width = width;
// ......
}
// bad
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
element.style.width = wrap.offsetWidth + 'px';
// ......
}
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
// ......
}
var len = elements.length;
while (len--) {
var element = elements[len];
// ......
}
var width = '200px';
parseInt(width, 10);
var num = 3.14;
!!num;
// good
var num = 3.14;
Math.ceil(num);
// bad
var num = 3.14;
parseInt(num, 10);
var str = '我是一个字符串';
var html = '<div class="cls">拼接HTML可以省去双引号转义</div>';
// 使用数组拼接字符串
var str = [
// 推荐换行开始并缩进开始第一个字符串, 对齐代码, 方便阅读.
'<ul>',
'<li>第一项</li>',
'<li>第二项</li>',
'</ul>'
].join('');
// 使用 + 拼接字符串
var str2 = '' // 建议第一个为空字符串, 第二个换行开始并缩进开始, 对齐代码, 方便阅读
+ '<ul>',
+ '<li>第一项</li>',
+ '<li>第二项</li>',
+ '</ul>';
test${index}
}}
#### 七、对象
+ 【强制】 使用对象字面量 {} 创建新 Object。
// good var obj = {};
// bad var obj = new Object();
+ 【强制】 对象创建时,如果一个对象的所有 属性 均可以不添加引号,则所有 属性 不得添加引号。
var info = { name: 'someone', age: 28 };
+ 【强制】 对象创建时,如果任何一个 属性 需要添加引号,则所有 属性 必须添加 '。
// good var info = { 'name': 'someone', 'age': 28, 'more-info': '...' };
// bad var info = { name: 'someone', age: 28, 'more-info': '...' };
+ 【建议】 for in 遍历对象时, 使用 hasOwnProperty 过滤掉原型中的属性。
var newInfo = {}; for (var key in info) { if (info.hasOwnProperty(key)) { newInfo[key] = info[key]; } }
#### 八、数组
+ 【强制】 使用数组字面量 [] 创建新数组,除非想要创建的是指定长度的数组。
// good var arr = [];
// bad var arr = new Array();
+ 【强制】 遍历数组不使用 for in。
- 数组对象可能存在数字以外的属性, 这种情况下 for in 不会得到正确结果.
var arr = ['a', 'b', 'c']; arr.other = 'other things'; // 这里仅作演示, 实际中应使用Object类型
// 正确的遍历方式 for (var i = 0, len = arr.length; i < len; i++) { console.log(i); }
// 错误的遍历方式 for (i in arr) { console.log(i); }
+ 【建议】 不因为性能的原因自己实现数组排序功能,尽量使用数组的 sort 方法。
- 自己实现的常规排序算法,在性能上并不优于数组默认的 sort 方法。以下两种场景可以自己实现排序:
- 需要稳定的排序算法,达到严格一致的排序结果。
- 数据特点鲜明,适合使用桶排。
+ 【建议】 清空数组使用 .length = 0。
#### 函数
+ 【建议】 通过 options 参数传递非数据输入型参数。
- 有些函数的参数并不是作为算法的输入,而是对算法的某些分支条件判断之用,此类参数建议通过一个 options 参数传递。
- 这种模式有几个显著的优势:
- boolean 型的配置项具备名称,从调用的代码上更易理解其表达的逻辑意义。
- 当配置项有增长时,无需无休止地增加参数个数,不会出现 removeElement(element, true, false, false, 3) 这样难以理解的调用代码。
- 当部分配置参数可选时,多个参数的形式非常难处理重载逻辑,而使用一个 options 对象只需判断属性是否存在,实现得以简化。
// bad /**
element.clearEventListeners();
}
}// good /**
element.clearEventListeners();
}
}
+ 【建议】 对于性能有高要求的场合,建议存在一个空函数的常量,供多处使用共享。
var EMPTY_FUNCTION = function () {};
function MyClass() { }
MyClass.prototype.abstractMethod = EMPTY_FUNCTION; MyClass.prototype.hooks.before = EMPTY_FUNCTION; MyClass.prototype.hooks.after = EMPTY_FUNCTION;
#### 面向对象
+ 【建议】 属性在构造函数中声明,方法在原型中声明。
- 原型对象的成员被所有实例共享,能节约内存占用。所以编码时我们应该遵守这样的原则:原型对象包含程序不会修改的成员,如方法函数或配置项。
function TextNode(value, engine) { this.value = value; this.engine = engine; }
TextNode.prototype.clone = function () { return this; };
```