又一天过去了。今天过得怎么样,梦想是不是更远了?
###蘑菇街前端开发规范-javascript篇
该文档定义了蘑菇街前端团队开发中 javascript 的规范,请参与前端开发的成员务必严格按照规范。该规范包含 4 部分,包括代码风格,javascript 语言规范,组件开发规范,文件命名规范。
代码风格良好的代码风格和,
代码风格的一致性是保证团队高效开发的前提
也是作为一支专业团队所必须具备的素质。
* 缩进how: 使用4个空格作为缩进方式,请将编辑器 tab 键为空格代替
why: 由于不同的编辑器对 tab 的显示不一致,为避免代码格式错乱,所以需统一设定。
* 变量命名风格how: 使用驼峰命名方式
why: getValue(驼峰命名) 和 get_value (下划线分割) 的不同地方是驼峰命名可以少一个字符。:)
// 类名:首字母大写,名词
ClassDefine
// 方法名:使用动词,或动名词结合,驼峰
defineFunctionName
// 变量名:与方法名类似,驼峰,对某些类型变量使用不同标识。
commonVariable // 普通变量
isBoolVariable // bool 类型变量,使用 is 开头
privateVariable // 私有变量,使用 开头
STATICVARIABLE // 常量,字母全部大写,中间使用 分隔
Other Tips:// 多个变量命名,’,’ 跟在变量名后。(推荐)1
var firstVari = 0,
secondVari = 1;
// 不建议写成以下格式,虽然在一些nodejs项目中你可能看到这样。(不推荐!)1
var firstVari = 0
,secondVari = 1;
// 另外不建议将右边赋值对齐。(不推荐!)1
var fristVari = 0;
var secondLongVari = 1;
* 代码格式how: 可参见 google c++ code guide
why: 统一的代码格式是作为一名专业程序员的首要素质,对代码风格,需要严格控制,而代码层面的规范,基本都是相通的。
1、每行代码长度
每行长度最长 100 字符,若对长度没概念,可设定编辑器屏幕显示区域来达到控制目的。
2、空格使用
1)一元操作符前后没有空格,for example:
1
i++;
i--;
2)二元操作符前后使用一个空格,for example:
1 | var myName = 'beile'; |
3、方法定义
1)括号前不留空格,’)’ 后使用一个空格,并紧跟 ‘{‘,多个参数使用 ‘, ‘ 隔开,for example:1
function getValue(firstParam, secondParam) {
// do something ...
}
4、条件控制
1)难以描述,请注意空格使用,for example:1
// if 语句
if (condition) {
// do something...
} else if (condition) {
// do another thing...
} else {
// do something...
}
// for 语句
for (var i = 0; i < 10; i++) {
// do something...
}
// while 语句
while (condition) {
// do something...
}
// switch 语句
stitch (condition) {
case 'case1':
// do something...
case 'case2':
// do something...
default:
// do something...
}
Other Tips:1、如果一行代码太长,请适时断行,for example:1
function theVeryVeryLongMethod(firstLongParams, secondLongParams, thirdLongParams) { // 不推荐!
// do something...
}
推荐,参数换行:1
function theVeryVeryLongMethod(firstLongParams,
secondLongParams, // 注意第二个参数的缩进
thirdLongParams) {
// do something...
}
或所有参数另起一行:1
function theVeryVeryLongMethod(
firstLongParams, // 参数另起一行,注意代码的缩进
secondLongParams,
thirdLongParams) {
// do something...
}
同理,在条件语句中,也需要遵循相同规则。for example:1
if (firstLongCondition
|| secondLongCondition // 根据运算符另起一行
|| thirdLongCondition) {
// do something...
}
javascript 语言规范由于 javascript 语言本身的特殊性和所具备的特性,所以在开发 javascript 代码时,我们需要遵循良好的开发规则,从而避免明显的性能问题和一些诡异的 bug。 什么是 javascript ?
1)永远记得使用 var 定义变量how: 定义变量的时候,加上 var 就好了。so easy ~
why: 若不加 var 变量,则变量的作用域是全局的,会引起一些诡异的 bug。1
var a = 123;
console.log(a); // 输出 123;
function bb() {
a = 234; // 未加 var 定义变量。
}
console.log(a); // 输出 234; a 的值变了。
2)永远记得使用分号对语句结尾how: 在语句结尾的时候,加上’;’ 就好了,also so easy ~
why: 虽然浏览器在运行 js 代码时,会在语句结尾自动加上分号,但是不写分号是一个不好的编程习惯,另由于上线时,js 代码会经过压缩,不加分号可能会导致压缩后的代码逻辑与自己所实现的不符。1
var b = 1 // 未加分号结尾
-1 == 0;
console.log(b); // 输出为 true; 原因是定义变量 b 时未加分号,导致与下面语句串联后,b 被赋值为 1 - 1;
所以为避免此种情况发生,请在语句结尾处加上';'
3) 创建基本类型时,不要使用 new 基本数据类型的包装对象why: 使用基本包装对象来创建基本数据类型是完全没有必要的,而且还会影响类型检测和逻辑判断1
var isShow = new Boolean(false);
console.log(typeof isShow); // 输出 'object'
if (isShow) { // 此处判断为 true;
console.log('isShow is true !');
}
同理,在创建字符串、数值等数据类型时,也不要使用基本数据类型的包装对象。
4) 数组、对象的创建how: 与基本数据类型类似,当你需要使用数组时,不要使用 Array 的构造函数来创建,而是使用数组的数组的直接字面量。1
// 使用 Array 构造函数,由于构造函数对参数的处理不够明确,会引起不必要的bug,
// 例如 new Array(3); 创建的是一个长度为 3 的空数组,而不是创建一个长度为 1、值为 3 的数组。
// 所以使用直接字面量来创建数组,代码的可读性会更好。也不会给后续埋坑。
var arr = [1, 2, 3]; // 推荐
var arr = new Array(1, 2, 3); // 不推荐!
// 同时推荐使用直接字面量创建对象
var obj = {}; // 推荐
var obj = new Object(); // 不推荐!
创建对象时,对象属性请注意缩进, for example:
1 | var user = { name: 'beile', // 冒号前不留空格,冒号后一个空格 sex: 'male' // 最后一个属性后不要加 ',',否则在部分浏览器下会报错 }; // 请不要忘记';' |
5) this 对象的使用how: 在你对 this 对象的指向不明确的时候,请在以下情况中使用 this。1
// 在构造函数中
function People(name) {
this.name = name;
}
// 在构造函数的原型扩展方法中
People.prototype.showName = function() {
console.log('my name ' + this.name);
}
// 另外如果使用的开发框架是 jQuery,推荐将事件触发的 dom 对象赋值给一个临时变量。for example:
$('.selector').click(function() {
var self = $(this); // 可避免在后续的方法中 $(this) 对象的指向不明。
});
6) 避免使用的方法how: 尽可能不用 eval、with
why: please tell me why …囧
7) 避免扩展内置对象的原型why: 对内置对象的扩展,会导致所创建的对象上都会有该属性。
对内置对象扩展,一个是内存的浪费,一个是在做某些逻辑判断时会导致问题,for example:1
Object.prototype.name = 'hello'; // 在 Object 上扩展原型 name
var b = {age: 18}; // 创建一个对象
for(var n in b) { // 遍历 b 中属性
console.log(n); // 输出 name 、 age
}
由于扩展了 Object 对象,所以会输出 name 和 age,当然你也可以通过以下代码避免出错:
1 | for(var n in b) { if(b.hasOwnProperty(n)) { console.log(n); 只输出 age } } |
但是还是需要记住的是,不要在原生对象上扩展原型。
推荐将方法定义到一个全局对象上来扩展 javascript 所没有的方法,for example:
1 | mx.util.string.getByte = function(str) { // do something... } |
8) 大字符串的创建方式how: 通过数组来创建大字符串
不推荐使用 ‘+’ 来拼接大字符串,for example:1
var listHtml = '<ul class="all_item">' +
'<li class="item">first item</li>' +
'<li class="item">second item</li>' +
'</ul>';
通过使用数组来创建大字符串是更好的方式,for example:
1 | var listHtml = [ '<ul class="all_item">', '<li class="item">first item</li>', '<li class="item">second item</li>', '</ul>' ].join(''); // 使用 jion 拼接 |
组件开发规范1)使用闭包来封装代码块how: 通过使用 var 声明变量和闭包的结合,可以有效控制代码块的作用域,从而避免暴露到全局中。
for example:1
(function($, Mx) {
var fruit = 'banner';
})(jQuery, Mx); // 虽然 jQuery 是全局变量,但最好在闭包中显式声明参数,这样可以方便知道该组件使用了哪些框架。另:最后不要忘了';'
2) 代码注释how: 遵循一定的规范,最重要的一点,不要怕注释多!
1、文件头部注释:
包含版权信息或开源协议等,不做强制要求。for example:1
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
2、自定义 Class 注释:(可以使用多个 * 将注释包裹)for example:
1 | /************************************************ * * 类的功能介绍,简述类的使用方法和功能。 * @require: a.js * b.js // 依赖的 js 文件 * @author: 作者 * @create: 创建时间 * @modify: 最后修改时间,对于通用组件不做强制要求。但是对于业务代码,每次修改需写明负责人和时间。 * ************************************************* |
3、方法的注释 for example:
1 | /** * 方法的功能介绍 * @param: {string} str * {object} options // 指明参数的类型 * @return: {string} str // 返回类型 * @author: 作者 * @create: 创建时间 * @modify: 最后修改时间 */ |
3)类构造方式 (function() {1
// 首先定义构造函数,
function MyClass(options) { // 参数可选
this.option = options;
}
// 通过原型扩展类
MyClass.prototype.method = function(params) {
// do something...
}
});
// 通过使用 new 来创建自定义类的实例
var myFirstClass = new MyClass({name: 'beile'});
Some Tips 为什么使用原型扩展类?
通过使用原型扩展类,在新建类的时候,只有类构造参数中的属性或方法是独立的内存,而原型上的方法的内存是共用的。
如果你想自定义类的某个方法,若不是全局的改动,直接使用覆盖新建对象的方式来达到个性化的目的,for example:
1 | myFirstCLass.method = function(params) { // do another thing... } ``` 而不要直接修改类的原型来达到目的, ```{bash} MyClass.prototype.method = function(params) { // 不推荐!除非你的所有对象实例都需要修改这个方法。 // do something... } |
建议在构造函数中只是定义类的属性,不要添加逻辑代码,以免业务变化时,不能很好的适应需求。for example:
// 在类中加了一段逻辑代码
function MyClass(options) { // 参数可选
this.option = options;
var myLogic = this.option.logic;
if (myLogic == 0) {
// do something...
}
}
这样,每次新建一个对象实例时,都会走这段逻辑。当我某个业务中不需要走 myLogic == 0 时,处理就会很麻烦。
推荐将初始逻辑代码放到一个 init 函数中。
4) 类继承// todo
文件组织规范// todo ..
javascript 代码技巧参考示例// todo ..