版本号 | 作者 | 时间 | 版本 | 内容摘要 |
---|---|---|---|---|
v1.0 | eleven | 2018-05-16 | 1.0.0 | 文档初始化 |
JS规范
1. 类型
简单类型:
- 字符串
- 数值
- 布尔类型
- null
- undefined
const foo = 1
let bar = foo
bar = 9
console.log(foo, bar) // 1, 9
复杂类型:
- object
- array
- function
const foo = [1, 2, 3]
const bar = foo
bar[0] = 9
console.log(foo[0], bar[0]) // 9, 9
2. 引用
const 和 let 都是块级作用域,var 是函数级作用域
- 对所有引用都使用 const,不要使用 var
推荐
const a = 1
const b = 2
不推荐
var a = 1
var b = 2
- 如果引用是可变动的,则使用 let
推荐
let count = 1
if (count < 10) {
count += 1
}
不推荐
var count = 1
if (count < 10) {
count += 1
}
3.对象
请使用字面量值创建对象
// bad
const a = new Object{}
// good
const a = {}
别使用保留字作为对象的键值,这样在 IE8 下不会运行
// bad
const a = {
default: {}, // default 是保留字
common: {}
}
// good
const a = {
defaults: {},
common: {}
}
请使用对象方法的简写方式
// bad
const item = {
value: 1,
addValue: function (val) {
return item.value + val
}
}
// good
const item = {
value: 1,
addValue(val) {
return item.value + val
}
}
请使用对象属性值的简写方式
const job = 'FrontEnd'
// bad
const item = {
job: job
}
// good
const item = {
job
}
对象属性值的简写方式要和声明式的方式分组
const job = 'FrontEnd'
const department = 'FS'
// bad
const item = {
sex: 'male',
job,
age: 25,
department
}
// good
const item = {
job,
department,
sex: 'male',
age: 25
}
4.数组
请使用字面量值创建数组
// bad
const items = new Array()
// good
const items = []
向数组中添加元素时,请使用 push 方法
const items = []
// bad
items[items.length] = 'test'
// good
items.push('test')
向数组中添加元素时,请使用 push 方法
// bad
const items = []
const itemsCopy = []
const len = items.length
let i
// bad
for (i = 0; i < len; i++) {
itemsCopy[i] = items[i]
}
// good
itemsCopy = [...items]
使用数组的 map 等方法时,请使用 return 声明,如果是单一声明语句的情况,可省略 return
// good
[1, 2, 3].map(x => {
const y = x + 1
return x * y
})
// good
[1, 2, 3].map(x => x + 1)
// bad
const flat = {}
[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
const flatten = memo.concat(item)
flat[index] = flatten
})
// good
const flat = {}
[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
const flatten = memo.concat(item)
flat[index] = flatten
return flatten
})
// bad
inbox.filter((msg) => {
const { subject, author } = msg
if (subject === 'Mockingbird') {
return author === 'Harper Lee'
} else {
return false
}
})
// good
inbox.filter((msg) => {
const { subject, author } = msg
if (subject === 'Mockingbird') {
return author === 'Harper Lee'
}
return false
})
5. 解构赋值
当需要使用对象的多个属性时,请使用解构赋值
// bad
function getFullName (user) {
const firstName = user.firstName
const lastName = user.lastName
return `${firstName} ${lastName}`
}
// good
function getFullName (user) {
const { firstName, lastName } = user
return `${firstName} ${lastName}`
}
// better
function getFullName ({ firstName, lastName }) {
return `${firstName} ${lastName}`
}
当需要使用数组的多个值时,请同样使用解构赋值
const arr = [1, 2, 3, 4]
// bad
const first = arr[0]
const second = arr[1]
// good
const [first, second] = arr
函数需要回传多个值时,请使用对象的解构,而不是数组的解构
// bad
function doSomething () {
return [top, right, bottom, left]
}
// 如果是数组解构,那么在调用时就需要考虑数据的顺序
const [top, xx, xxx, left] = doSomething()
// good
function doSomething () {
return { top, right, bottom, left }
}
// 此时不需要考虑数据的顺序
const { top, left } = doSomething()
6.字符串
字符串统一使用单引号的形式 ' '
// bad
const department = "FS"
// good
const department = 'FS'
字符串太长的时候,请不要使用字符串连接符换行 \,而是使用 +
const str = '凹凸实验室 凹凸实验室 凹凸实验室' +
'凹凸实验室 凹凸实验室 凹凸实验室' +
'凹凸实验室 凹凸实验室'
程序化生成字符串时,请使用模板字符串
const test = 'test'
// bad
const str = ['a', 'b', test].join()
// bad
const str = 'a' + 'b' + test
// good
const str = `ab${test}`
7.函数
请使用函数声明,而不是函数表达式
// bad
const foo = function () {
// do something
}
// good
function foo () {
// do something
}
不要在非函数代码块中声明函数
// bad
if (isUse) {
function test () {
// do something
}
}
// good
let test
if (isUse) {
test = () => {
// do something
}
}
不要使用 arguments,可以选择使用 ...
// bad
function test () {
const args = Array.prototype.slice.call(arguments)
return args.join('')
}
// good
function test (...args) {
return args.join('')
}
不要更改函数参数的值
// bad
function test (opts) {
opts = opts || {}
}
// good
function test (opts = {}) {
// ...
}
8.分号
我们遵循 Standard 的规范,不使用分号。
// bad
const test = 'good';
(function () {
const str = 'hahaha';
})()
// good
const test = 'good'
;(() => {
const str = 'hahaha'
})();
9.大括号风格
在编程过程中,大括号风格与缩进风格紧密联系,用来描述大括号相对代码块位置的方法有很多。
推荐
if (foo) {
bar()
} else {
baz()
}
10.变量命名
团队约定使用驼峰式命名
11.逗号空格
逗号前后的空格可以提高代码的可读性,团队约定在逗号后面使用空格,逗号前面不加空格。
推荐
var foo = 1, bar = 2
不推荐
var foo = 1,bar = 2
var foo = 1 , bar = 2
var foo = 1 ,bar = 2
12.变量声明
JavaScript 允许在一个声明中,声明多个变量。团队约定在声明变量时,一个声明只能有一个变量
推荐
var a
var b
var c
不推荐
var a, b, c
13.函数声明的空格
团队约定函数括号要加空格
推荐
function func (x) {
// ...
}
不推荐
function func(x) {
// ...
}
14.操作符的空格
团队约定操作符前后都需要添加空格
推荐
var sum = 1 + 2
不推荐
var sum = 1+2
15.三元条件判断(if 的快捷方法)
推荐
var sum = a=== 10 ? true : false;
不推荐
var sum;
if(a === 10){
sum = true;
} else {
sum = false
}
16.Js遍历数组的方式及其性能对比
Js数组遍历,基本有for、优化后的for、forin、forEach、while、forin、map、filter等一些方法,下面进行对比分析:
/**
* for 循环
* */
let arr = [];
let max = 10000000;
setTimeout(function () {
//初始化arr
for (let i = 0; i < max; i++) {
arr[i] = i + 1;
}
}, 1);
/**
* 检测简单的for循环
* */
function testDefaultFor(){
let startTime, endTime, sum = 0;
startTime = new Date();
for(let i = 0; i < arr.length; i++){
sum += arr[i];
}
endTime = new Date();
console.log('普通for循环所需要时间:' + (endTime - startTime));
}
/**
* 检测优化后的for循环
* */
function testDefaultFor2(){
let startTime, endTime, sum = 0;
startTime = new Date();
for(let i = 0, len = arr.length; i < len; i++){
sum += arr[i];
}
endTime = new Date();
console.log('普通for循环所需要时间:' + (endTime - startTime));
}
/**
* 检测forEach循环所需时间
* */
function testDefaultForeach(){
let startTime, endTime, sum = 0;
startTime = new Date();
arr.forEach(function(d, i){
sum += d;
})
endTime = new Date();
console.log('foreach循环所需要时间:' + (endTime - startTime));
}
/**
* 检测while循环所需时间
* */
function testDefaultWhile(){
let startTime, endTime, sum = 0, i = 0;
startTime = new Date();
while (i < max){
sum += arr[i]*1;
i++;
}
endTime = new Date();
console.log('while循环所需要时间:' + (endTime - startTime));
}
/**
* 检测while循环所需时间
* */
function testDefaultForIn(){
let startTime, endTime, sum = 0;
startTime = new Date();
for(let i in arr){
sum += i*1;
}
endTime = new Date();
console.log('forin循环所需要时间:' + (endTime - startTime));
}
/**
* 检测map循环所需时间
* */
function testDefaultMap(){
let startTime, endTime, sum = 0;
startTime = new Date();
arr.map(function(d){
sum += d*1;
});
endTime = new Date();
console.log('map循环所需要时间:' + (endTime - startTime));
}
/**
* 检测filter循环所需时间
* */
function testDefaultFilter(){
let startTime, endTime, sum = 0;
startTime = new Date();
arr.filter(function(d){
sum += d*1;
});
endTime = new Date();
console.log('filter循环所需要时间:' + (endTime - startTime));
}
最终得到的结果是:
- 普通for循环所需要时间:99
- 普通for循环所需要时间:76
- foreach循环所需要时间:431
- while循环所需要时间:81
- forin循环所需要时间:1317
- map循环所需要时间:1513
- filter循环所需要时间:493
- <font color="#f00">综合而言,forin与map最慢,优化后的for循环最快。</font>
17.总是使用带类型的判断符比较判断
总是使用 === 精确的比较操作符,而不是==,避免在判断的过程中,由 JavaScript 的强制类型转换所造成的困扰。
18.变量赋值时的逻辑操作
逻辑操作符 || 和 && 也可被用来返回布尔值。如果操作对象为非布尔对象,那每个表达式将会被自左向右地做真假判断。基于此操作,最终总有一个表达式被返回回来。这在变量赋值时,是可以用来简化你的代码的。
推荐
x = x || y || 1
不推荐
if(!x){
if(!y){
x = 1
} else {
x = y
}
}
19.代码注释规范
注释是你自己与你的小伙伴们了解代码写法和目的的唯一途径。特别是在写一些看似琐碎的无关紧要的代码时,由于记忆点不深刻,注释就变得尤为重要了。
函数注释:
推荐
/**
* 测试的fun函数
* @param id 某个订单的订单id
* @param type 订单类型 0:未支付;1:支付成功;2:支付中;3:支付失败;
* @param callback 回调函数
* @returns {Promise.<TRsult>}
*/
function testFun(id, type, callback){
..........
}
单行注释:
推荐
var test = '你好'; // 测试的字段注释
20.使用严格模式
use strict;
........
为什么使用严格模式:
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的Javascript做好铺垫。
"严格模式"体现了Javascript更合理、更安全、更严谨的发展方向,包括IE 10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱它。
另一方面,同样的代码,在"严格模式"中,可能会有不一样的运行结果;一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行。掌握这些内容,有助于更细致深入地理解Javascript,让你变成一个更好的程序员。
21.禁用eval()
由于 eval 方法比较 evil,所以我们约定禁止使用该方法
22.禁用with()
由于 with 方法会产生神奇的作用域,所以我们也是禁止使用该方法的