1. 程式人生 > >寫出優雅的js程式碼

寫出優雅的js程式碼

一.常量相關

1.定義常量

var a=1; // 錯誤:"var"定義的"常量"是可變的,在宣告一個常量時,該常量在整個程式中都應該是不可變的。
正解:
const a=1

2.給常量賦值

let lastName = fullName[1]; // 錯誤:如果fullName=[],那麼fullName[1]=undefined
let propertyValue = Object.attr; // 錯誤:如果Object={},那麼Object.attr=undefined
複製程式碼

正解: 對於引用資料型別,要做好兜底

let lastName = fullName[1] || ''
let
propertyValue=Object.attr||0 複製程式碼

3.使用說明性常量

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.不知道這條資料是什麼意思
);
複製程式碼

正解: 用常量名來解釋長程式碼的含義

const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);
複製程式碼

二.函式相關

1.對於for迴圈優先使用指令式程式設計

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/…

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

if (a === 1) {
	...
} else if (a ===2) {
	...
} else if (a === 3) {
	...
} else {
   ...
}
複製程式碼

正解:

switch(a) {
   case 1:
   	....
   case 2:
   	....
   case 3:
   	....
  default:
   	....
}
Or
let handler = {
    1: () => {....},
    2: () => {....}.
    3: () => {....},
    default: () => {....}
}

    handler[a]() || handler['default']()
複製程式碼

3.使用正則表示式

const imgType='jpg'
if(imgType==='jpg'||imgType==='png'||imgType==='gif'){
    console.log('hello image')
}
複製程式碼

正解:使用match匹配正則表示式

const imgType='jpg'
if(imgType.match(/.*?(gif|png|jpg)/gi)){
    console.log('hello image')
}
複製程式碼

三.使用ES6新語法(只舉例常用語法)

1.使用箭頭函式

function method() {
  console.log('hello')
}
複製程式碼

正解:

let method=()=> {
  console.log('hello')
}
method(); // hello
複製程式碼

2.連線字串

var message = 'Hello ' + name + ', it\'s ' + time + ' now' //錯誤:採用傳統加號,看著很冗餘
正解:採用模板字元
var message = `Hello ${name}, it's ${time} now`

3.使用解構賦值

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];
複製程式碼

正解:使用結構賦值

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迴圈

for(let i=0;i<list.length;i++){
    console.log(list[i])
}
複製程式碼

正解:

for(let i of list){
    console.log(i)
}
複製程式碼

注意: 對於es6,for迴圈中 in 和 of 的區別: in是針對物件而言的,of是針對陣列而言的

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 in array){
    console.log(i); // 1,2,3
}
複製程式碼

5.使用繼承class類,而不是 ES5 的 Function

這裡只用ES6語法說明

// 定義類
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可以保證程式碼符合一定的風格,有起碼的可讀性

{
  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],
    // 堅定的 semicolon-less 擁護者
    semi: [2, 'never'],
  },
  env: {
    browser: true,
  },
}
複製程式碼