教育行业A股IPO第一股(股票代码 003032)

全国咨询/投诉热线:400-618-4000

写出优雅的JS代码

更新时间:2018年12月19日15时29分 来源:传智播客 浏览次数:

一.常量相关
1.定义常量
[JavaScript] 纯文本查看 复制代码
1
var a=1; // 错误:"var"定义的"常量"是可变的,在声明一个常量时,该常量在整个程序中都应该是不可变的。

正解:
[JavaScript] 纯文本查看 复制代码
1
const a=1

2.给常量赋值
[JavaScript] 纯文本查看 复制代码
1
2
let lastName = fullName[1]; // 错误:如果fullName=[],那么fullName[1]=undefined
let propertyValue = Object.attr; // 错误:如果Object={},那么Object.attr=undefined

正解: 对于引用数据类型,要做好兜底
[JavaScript] 纯文本查看 复制代码
1
2
let lastName = fullName[1] || ''
let propertyValue=Object.attr||0

3.使用说明性常量
[JavaScript] 纯文本查看 复制代码
1
2
3
4
5
6
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(
  address.match(cityZipCodeRegex)[1], // 错误:1.address.match(cityZipCodeRegex)可能为null,那当前这种写法就会报错
  address.match(cityZipCodeRegex)[2], // 错误:2.不知道这条数据是什么意思
);

正解: 用常量名来解释长代码的含义
[JavaScript] 纯文本查看 复制代码
1
2
3
4
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);

二.函数相关

1.对于for循环优先使用命令式编程
[JavaScript] 纯文本查看 复制代码
1
2
3
4
5
6
7
var result=[]
var a=[1,2,3,4,5,6]
for(i = 1; i <= 10; i++) {
   if(a[i]>4){
      result.push(a[i])
   }
}

正解: 使用命令式编程(find、soma、every、map、filter、sort、shift、pop、join),各种用法可以参考:developer.mozilla.org/en-US/docs/…
[JavaScript] 纯文本查看 复制代码
1
2
var a=[1,2,3,4,5,6]
const result = a.filter(item => item> 4);

备注: forEach不能使用break结束循环体,但可以使用 return 或 return false 跳出当前循环,效果与 for 中 continue 一样,如果要一次性结束所有循环,还是老老实实使用for方法:for(let list of lists)。
2.函数中不要过多的采用if else
[JavaScript] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
9
if (a === 1) {
        ...
} else if (a ===2) {
        ...
} else if (a === 3) {
        ...
} else {
   ...
}

正解:
[JavaScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
switch(a) {
   case 1:
           ....
   case 2:
           ....
   case 3:
           ....
  default:
           ....
}
Or
let handler = {
    1: () => {....},
    2: () => {....}.
    3: () => {....},
    default: () => {....}
}
    handler[a]() || handler['default']()

3.使用正则表达式
[JavaScript] 纯文本查看 复制代码
1
2
3
4
const imgType='jpg'
if(imgType==='jpg'||imgType==='png'||imgType==='gif'){
    console.log('hello image')
}

正解:使用match匹配正则表达式
[JavaScript] 纯文本查看 复制代码
1
2
3
4
const imgType='jpg'
if(imgType.match(/.*?(gif|png|jpg)/gi)){
    console.log('hello image')
}

三.使用ES6新语法(只举例常用语法)

1.使用箭头函数
[JavaScript] 纯文本查看 复制代码
1
2
3
function method() {
  console.log('hello')
}

正解:
[JavaScript] 纯文本查看 复制代码
1
2
3
4
let method=()=> {
  console.log('hello')
}
method(); // hello

2.连接字符串
[JavaScript] 纯文本查看 复制代码
1
var message = 'Hello ' + name + ', it\'s ' + time + ' now' //错误:采用传统加号,看着很冗余

正解:采用模板字符
[JavaScript] 纯文本查看 复制代码
1
var message = `Hello ${name}, it's ${time} now`

3.使用解构赋值
[JavaScript] 纯文本查看 复制代码
1
2
3
4
5
6
7
var user = { name: 'dys', age: 1 };
var name = user.name;
var age = user.age;
 
var fullName = ['jackie', 'willen'];
var firstName = fullName[0];
var lastName = fullName[1];

正解:使用结构赋值
[JavaScript] 纯文本查看 复制代码
1
2
3
4
5
const user = {name:'dys', age:1};
const {name, age} = user;  // 当需要被赋值的字段和对象中定义的字段相同时,就可以使用这种方法,相当于const name=user.name
 
var fullName = ['jackie', 'willen'];
const [firstName, lastName] = fullName;

4.如必须使用for循环使用for..in或for..of循环
[JavaScript] 纯文本查看 复制代码
1
2
3
for(let i=0;i<list.length;i++){
    console.log(list[i])
}

正解:
[JavaScript] 纯文本查看 复制代码
1
2
3
for(let i of list){
    console.log(i)
}

注意: 对于es6,for循环中 in 和 of 的区别:in可以是给对象使用也可以是对数组使用,of只能是针对数组而言的
[JavaScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
const object={a:1,b:2,c:3}
for(let i in object){
    console.log(i); //a,b,c
}
 
const array=[1,2,3]
for(let i of array){
    console.log(i); // 1,2,3
}
for(let i in array){
    console.log(i); // 0,1,2
}

5.使用继承class类,而不是 ES5 的 Function这里只用ES6语法说明
[JavaScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
// 定义类class point{    constructor(x,y){        this.x=x;        this.y=y;    }    toString(){        return `${this.x},${this.y}`    }}var p=new point(1,2)p.toString() // 1,2// 继承类
class mainPoint extends point {
    constructor(x, y, z) {
        super(x, y);
        this.z = z;
    }
 
    toString() {
        return this.z + ' ' + super.toString();
    }
}
var mainpoint=new point(1,2,3)
mainpoint.toString() // 3 1,2

四.ESLint的配置

ESLint可以保证代码符合一定的风格,有起码的可读性
[JavaScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
  parser: 'babel-eslint',
  extends: ['airbnb', 'plugin:react/recommended', 'prettier', 'prettier/react'],
  plugins: ['react', 'prettier'],
  rules: {
    // prettier 配置用于自动化格式代码
    'prettier/prettier': [
      'error',
      {
        singleQuote: true,
        semi: false,
        trailingComma: 'all',
        bracketSpacing: true,
        jsxBracketSameLine: true,
      },
    ],
    // 一个函数的复杂性不超过 10,所有分支、循环、回调加在一起,在一个函数里不超过 10 个
    complexity: [2, 10],
    // 一个函数的嵌套不能超过 4 层,多个 for 循环,深层的 if-else,这些都是罪恶之源
    'max-depth': [2, 4],
    // 一个函数最多有 3 层 callback,使用 async/await
    'max-nested-callbacks': [2, 3],
    // 一个函数最多 5 个参数。参数太多的函数,意味着函数功能过于复杂,请拆分
    'max-params': [2, 5],
    // 一个函数最多有 50 行代码,如果超过了,请拆分之,或者精简之
    'max-statements': [2, 50],



作者:传智播客前端与移动开发培训学院

首发: http://web.itcast.cn

0 分享到:
和我们在线交谈!