传值
所有需要传值到页面的,都需要进行判空
if(value.hour !=undefined && value.minute !=undefined){
tideTimeArr.push(value.hour+':'+value.minute)
}else{
tideTimeArr.push("")
}
if(data.WINDPWR == undefined){
data.WINDPWR=""
}
引用
const
和 let
都是块级作用域,var
是函数级作用域
对所有引用都使用
const
,不要使用var
| // badvar a = 1var b = 2// goodconst a = 1const b = 2 | | :—- |如果引用是可变动的,则使用
let
| // badvar count = 1if (count < 10) { count += 1}// goodlet count = 1if (count < 10) { count += 1} | | :—- |
对象
请使用字面量值创建对象 | // badconst a = new Object{}// goodconst a = {} | | :—- |
别使用保留字作为对象的键值,这样在 IE8 下不会运行 | // badconst a = { default: {}, // default 是保留字 common: {}}// goodconst a = { defaults: {}, common: {}} | | :—- |
请使用对象方法的简写方式 | // badconst item = { value: 1, addValue: function (val) { return item.value + val }}// goodconst item = { value: 1, addValue(val) { return item.value + val }} | | :—- |
请使用对象属性值的简写方式 | const job = ‘FrontEnd’// badconst item = { job: job}// goodconst item = { job} | | :—- |
对象属性值的简写方式要和声明式的方式分组 | const job = ‘FrontEnd’const department = ‘JDC’// badconst item = { sex: ‘male’, job, age: 25, department}// goodconst item = { job, department, sex: ‘male’, age: 25} | | :—- |
数组
请使用字面量值创建数组 | // badconst items = new Array()// goodconst items = [] | | :—- |
向数组中添加元素时,请使用
push
方法 | const items = []// baditems[items.length] = ‘test’// gooditems.push(‘test’) | | :—- |使用拓展运算符
...
复制数组 | // badconst items = []const itemsCopy = []const len = items.lengthlet i// badfor (i = 0; i < len; i++) { itemsCopy[i] = items[i]}// gooditemsCopy = […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)
// badconst flat = {}[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => { const flatten = memo.concat(item) flat[index] = flatten})
// goodconst flat = {}[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => { const flatten = memo.concat(item) flat[index] = flatten return flatten})
// badinbox.filter((msg) => { const { subject, author } = msg if (subject === ‘Mockingbird’) { return author === ‘Harper Lee’ } else { return false }})
// goodinbox.filter((msg) => { const { subject, author } = msg if (subject === ‘Mockingbird’) { return author === ‘Harper Lee’ }
return false}) | | :—- |
解构赋值
当需要使用对象的多个属性时,请使用解构赋值 | // badfunction getFullName (user) { const firstName = user.firstName const lastName = user.lastName return
${firstName} ${lastName}
}// goodfunction getFullName (user) { const { firstName, lastName } = user return${firstName} ${lastName}
}// betterfunction getFullName ({ firstName, lastName }) { return${firstName} ${lastName}
} | | :—- |当需要使用数组的多个值时,请同样使用解构赋值 | const arr = [1, 2, 3, 4]
// badconst first = arr[0]const second = arr[1]
// goodconst [first, second] = arr | | :—- |函数需要回传多个值时,请使用对象的解构,而不是数组的解构 | // badfunction doSomething () { return [top, right, bottom, left]}// 如果是数组解构,那么在调用时就需要考虑数据的顺序const [top, xx, xxx, left] = doSomething()// goodfunction doSomething () { return { top, right, bottom, left }}// 此时不需要考虑数据的顺序const { top, left } = doSomething() | | :—- |
字符串
字符串统一使用单引号的形式
''
| // badconst department = “JDC”// goodconst department = ‘JDC’ | | :—- |字符串太长的时候,请不要使用字符串连接符换行
\
,而是使用+
| const str = ‘凹凸实验室 凹凸实验室 凹凸实验室’ + ‘凹凸实验室 凹凸实验室 凹凸实验室’ + ‘凹凸实验室 凹凸实验室’ | | :—- |程序化生成字符串时,请使用模板字符串 | const test = ‘test’// badconst str = [‘a’, ‘b’, test].join()// badconst str = ‘a’ + ‘b’ + test// goodconst str =
ab${test}
| | :—- |
函数
请使用函数声明,而不是函数表达式 | // badconst foo = function () { // do something}// goodfunction foo () { // do something} | | :—- |
不要在非函数代码块中声明函数 | // badif (isUse) { function test () { // do something }}// goodlet testif (isUse) { test = () => { // do something }} | | :—- |
不要使用
arguments
,可以选择使用...
arguments
只是一个类数组,而...
是一个真正的数组
原型
- 使用
class
,避免直接操作prototype
| // badfunction Queue (contents = []) { this._queue = [..contents]}Queue.prototype.pop = function () { const value = this._queue[0] this._queue.splice(0, 1) return value}// goodclass Queue { constructor (contents = []) { this._queue = […contents] } pop () { const value = this._queue[0] this._queue.splice(0, 1) return value }} | | :—- |
模块
使用标准的 ES6 模块语法
import
和export
| // badconst util = require(‘./util’)module.exports = util// goodimport Util from ‘./util’export default Util// betterimport { Util } from ‘./util’export default Util | | :—- |不要使用
import
的通配符*
,这样可以确保你只有一个默认的 export | // badimport * as Util from ‘./util’// goodimport Util from ‘./util’ | | :—- |
迭代器
- 不要使用
iterators
| const numbers = [1, 2, 3, 4, 5]// badlet sum = 0for (let num of numbers) { sum += num}// goodlet sum = 0numbers.forEach(num => sum += num)// betterconst sum = numbers.reduce((total, num) => total + num, 0) | | :—- |
对象属性
- 使用
.
来访问对象属性 | const joke = { name: ‘haha’, age: 28}// badconst name = joke[‘name’]// goodconst name = joke.name | | :—- |
变量声明
声明变量时,请使用
const
、let
关键字,如果没有写关键字,变量就会暴露在全局上下文中,这样很可能会和现有变量冲突,另外,也很难明确该变量的作用域是什么。这里推荐使用const
来声明变量,我们需要避免全局命名空间的污染。 | // baddemo = new Demo()// goodconst demo = new Demo() | | :—- |将所有的
const
和let
分组 | // badlet aconst blet cconst dlet e// goodconst bconst dlet alet clet e | | :—- |
Hoisting
var
存在变量提升的情况,即var
声明会被提升至该作用域的顶部,但是他们的赋值并不会。而const
和let
并不存在这种情况,他们被赋予了 Temporal Dead Zones, TDZ | function example () { console.log(notDefined) // => throws a ReferenceError}function example () { console.log(declareButNotAssigned) // => undefined var declaredButNotAssigned = true}function example () { let declaredButNotAssigned console.log(declaredButNotAssigned) // => undefined declaredButNotAssigned = true}function example () { console.log(declaredButNotAssigned) // => throws a ReferenceError console.log(typeof declaredButNotAssigned) // => throws a ReferenceError const declaredButNotAssigned = true} | | :—- |匿名函数的变量名会提升,但函数内容不会 | function example () { console.log(anonymous) // => undefined anonymous() var anonymous = function () { console.log(‘test’) }} | | :—- |
命名的函数表达式的变量名会被提升,但函数名和函数函数内容并不会 | function example() { console.log(named) // => undefined named() // => TypeError named is not a function superPower() // => ReferenceError superPower is not defined var named = function superPower () { console.log(‘Flying’) }}function example() { console.log(named) // => undefined named() // => TypeError named is not a function var named = function named () { console.log(‘named’) }} | | :—- |
分号
- 我们团队约定,再语句结束之后使用分号,以便使代码更清晰。
- 下列关键字后必须有大括号(即使代码块的内容只有一行):
if
,else
,for
,while
,do
,switch
,try
,catch
,finally
,with
。 | // goodconst test = ‘good’;(() => { const str = ‘hahaha’;})(); | | :—- |
// not good
if (condition)
doSomething();
// good
if (condition) {
doSomething();
}
null
适用场景:
- 初始化一个将来可能被赋值为对象的变量
- 与已经初始化的变量做比较
- 作为一个参数为对象的函数的调用传参
- 作为一个返回对象的函数的返回值
不适用场景:
- 不要用null来判断函数调用时有无传参
- 不要与未初始化的变量做比较
// not good
function test(a, b) {
if (b === null) {
// not mean b is not supply
...
}
}
let a;
if (a === null) {
...
}
// good
let a = null;
if (a === null) {
...
}
undefined
永远不要直接使用undefined进行变量判断;
使用typeof和字符串’undefined’对变量进行判断。
// not good
if (person === undefined) {
...
}
// good
if (typeof person === 'undefined') {
...
}
jshint
for-in里一定要有hasOwnProperty的判断;查找一个对象是否有某个属性,但是不会去查找它的原型链
// good
for (key in obj) {
if (obj.hasOwnProperty(key)) {
// be sure that obj[key] belongs to the object and was not inherited
console.log(obj[key]);
}
}
不要在内置对象的原型上添加方法,如Array, Date;
// not good
Array.prototype.count = function(value) {
return 4;
};
不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;
// not good
let x = 1;
function test() {
if (true) {
let x = 0;
}
x += 1;
}
变量不要先使用后声明;
// not good
function test() {
console.log(x);
let x = 1;
}
不要在一句代码中单单使用构造函数,记得将其赋值给某个变量;
// not good
new Person();
// good
let person = new Person();
不要在一些不需要的地方加括号,例:delete(a.b);
// not good
delete(obj.attr);
// good
delete obj.attr;
数组中不要存在空元素;
// not good
let a = [1, , , 2, 3];
不要在循环内部声明函数;
// not good
let nums = [];
for (let i = 0; i < 10; i++) {
(function(i) {
nums[i] = function(j) {
return i + j;
};
}(i));
}
不要使用未声明的变量;
不要声明了变量却不使用;
debugger不要出现在提交的代码里;
杂项
不要混用tab和space;
不要在一处使用多个tab或space;
对上下文this的引用只能使用’_this’来命名;
行尾不要有空白字符;
switch的falling through和no default的情况一定要有注释特别说明;
不允许有空的代码块。
// not good
let a = 1;
function Person() {
// not good
let me = this;
// good
let _this = this;
// good
let that = this;
// good
let self = this;
}
// good
switch (condition) {
case 1:
case 2:
...
break;
case 3:
...
// why fall through
case 4
...
break;
// why no default
}
// not good with empty block
if (condition) {
}