2. Creating Functions
Use function expressions instead of declarations 使用函数表达式而不是函数声明
Function Declarations vs. Function Expressions
//Function Declaration *********Hoisted********
function functionName(){
//function statements
}
//Function Expression ***********Not Hoisted***********
const functionName = function(){
//function statements
};
"use strict";
const today = new Date();
// Hoisted,声明之前使用不会抛错
const weekAgo = weekAgoDate();
//函数声明
function weekAgoDate() {
const date = new Date();
date.setDate(date.getDate() - 7);
return date;
};
console.log(today);
console.log(weekAgo);
"use strict";
const today = new Date();
//Not Hoisted,在表达式之前使用会抛错
const weekAgo = weekAgoDate();
//函数表达式
const weekAgoDate = function() {
const date = new Date();
date.setDate(date.getDate() - 7);
return date;
};
console.log(today);
console.log(weekAgo);
显然为了代码逻辑顺序一致,我们不喜欢Hoisted的执行。强制要求使用函数表达式定义。
规则:func-style
Don't use the new keyword to construct function 不要使用new Function构造函数
"use strict";
const abRatio = 0.95;
const input = 52;
const abFactor = new Function("value", "return (value * abRatio)");
console.log(`abFactor: ${abFactor(input)}`);
这种声明函数的方式有性能问题且不安全。
规则:no-new-func
Leave parameter values untounched 不修改输入参数
保持输入参数不变,有利于我们查看代码值的变化,方便调试。
"use strict";
const bonusResult = (input) => {
if (input <= 100) {
input = 100
} else if (input > 100 && input < 500) {
input = input * 1.5;
} else if (input >= 500) {
input = input * 2;
}
return input;
}
console.log(bonusResult(50));
console.log(bonusResult(150));
console.log(bonusResult(600));
如下代码可以方便输出input参数前后的差值。
"use strict";
const bonusResult = (input) => {
let result;
if (input <= 100) {
result = 100
} else if (input > 100 && input < 500) {
result = input * 1.5;
} else if (input >= 500) {
result = input * 2;
}
const difference = (result - input);
return [result, difference];
}
console.log(bonusResult(50));
console.log(bonusResult(150));
console.log(bonusResult(600));
Use arrow syntax for anonymous functions 匿名函数使用箭头函数句法
"use strict";
const projections = [15.2, 33.8, 17.3, 22.4];
//const bestCase = projections.map(function(proj) {
// return ((proj * 1.5).toFixed(1));
//});
//修改成箭头函数
const bestCase = projections.map((proj) => {
return ((proj * 1.5).toFixed(1));
});
console.log (bestCase);
Rely on implicit return only when obvious 只有明显时才依赖隐式return
Arrow Function Syntax
(a) => {
return (a*2);
}
(a) => return (a*2);
(a) => (a*2);
a => (a*2);
参数一律加括号,如果只有一行代码,方法体不加{},也不要写return
const bestCase = projections.map(proj => {
return ((proj * 1.5).toFixed(1));
});
//简洁写法
const bestCase = projections.map((proj) => ((proj * 1.5).toFixed(1)));
规则:arrow-parents , arrow-body-style
3. Creating Classes
Use PascalCase for naming classes and constructors
PascalCase :对类和构造函数的命名,要求使用PascalCase, 即首字母大写,例如:CartLabel
camelCase : 对函数和变量的命名,要求使用驼峰命名, 例如: cartLable
class Cart {
constructor(options) {
this.user = options.user;
}
}
const currentCart = new Cart({
user: loggedInUser,
});
规则:new-cap
Use this only in classes or constructors this只用于类与构造函数中
"use strict";
const loggedInUser = "sashavodnik";
const taxRate = 0.075;
class Cart {
constructor(options) {
this.user = options.user;
}
calcTax(rate) {
this.tax = this.total * rate;
}
}
// const calcTax = (rate) => {
// this.tax = this.total * rate;
// };
const currentCart = new Cart({
user: loggedInUser,
});
currentCart.total = 100;
currentCart.calcTax(taxRate);
console.log(currentCart);
运行结果:Cart {user: "sashavodnik", total: 100, tax: 7.5}
Return this from methods 方法返回this。 方便链式调用。
"use strict";
const loggedInUser = "sashavodnik";
const taxRate = 0.075;
class Cart {
constructor(options) {
this.user = options.user;
}
calcTax(rate) {
this.tax = this.total * rate;
return this; //返回this
}
calcShipping() {
if (this.total > 50) {
this.shipping = 5;
} else {
this.shipping = 10;
}
return this; //返回this
}
calcGrandTotal() {
if (this.tax && this.shipping) {
this.grandTotal = this.total + this.tax + this.shipping;
}
return this; //返回this
}
}
const currentCart = new Cart({
user: loggedInUser,
});
currentCart.total = 100;
// currentCart.calcTax(taxRate);
// currentCart.calcShipping();
// currentCart.calcGrandTotal();
//==========链式调用
currentCart
.calcTax(taxRate)
.calcShipping()
.calcGrandTotal();
console.log(currentCart);
Don't assign this to another variable 不要把this赋予其他变量
"use strict";
const loggedInUser = "sashavodnik";
const taxRate = 0.075;
class Cart {
constructor(options) {
this.user = options.user;
}
calcTax(rate) {
this.tax = this.total * rate;
return this;
}
calcShipping() {
if (this.total > 50) {
this.shipping = 5;
} else {
this.shipping = 10;
}
return this;
}
calcGrandTotal() {
if (this.tax && this.shipping) {
this.grandTotal = this.total + this.tax + this.shipping;
}
return this;
}
/*
logCart() {
const that = this; //this赋值给了临时变量保存context
return function() {
console.log(that);
};
}
*/
logCart() {
console.log(this);
}
}
const currentCart = new Cart({
user: loggedInUser,
});
currentCart.total = 100;
currentCart
.calcTax(taxRate)
.calcShipping()
.calcGrandTotal();
//window.addEventListener("load", currentCart.logCart());
window.addEventListener('load', currentCart.logCart.call(currentCart)); //明确的context
4. Creating Modules
Configure module settings in ESLint
Default export constants when possible 尽可能使用export default const常量
Use const for Module Exports
- Provides predictable interface
- No unexpected results
Default Export from Modules
- Export a single thing
- Keep modules focused
The core ESLint utility doesn't support rules the default exports, but you can explore ESLint add ons for this purpose ,
https://www.github.com/benmosher/eslint-plugin-import
规则:prefer-const
5. Destructuring
Use object destructuring 使用对象析构
Use array destructuring 使用数组析构
6. JavaScript Features to Avoid
Avoid eval
Avoid == and !=
Avoid with
Avoid unary increments and decrements