如何讓你的JavaScript代碼更優雅

寫了好多年的JavaScript代碼,你的代碼是否是能夠更加優雅?下面整理了一些優化代碼的建議,你們能夠酌情作一下參考,但願能給到你們一些幫助。html

1.推薦使用全等和不全等操做符

ECMAScript 提供兩組操做符:相等和不相等(== 和 !=)——先轉換再比較,全等和不全等(=== 和!==)——僅比較而不轉換前端

除了在比較以前不轉換操做數以外,全等和不全等操做符與相等和不相等操做符沒有什麼區別編程

以下所示:數組

var result1 = ("66" == 66);    //true,由於轉換後相等 
var result2 = ("66" === 66);  //false,由於不一樣的數據類型不相等
複製代碼

要記住:null == undefined 會返回 true,由於它們是相似的值;但 null === undefined 會返 回 false,由於它們是不一樣類型的值。緩存

因爲相等和不相等操做符存在類型轉換問題,而爲了保持代碼中數據類型的完整性,推薦使用全等和不全等操做符。若是變量的類型是已經肯定了的,那麼使用==是根本不必的;若是類型不肯定,應該手動作一下轉換:bash

var code = "5";
if(parseInt(code) === 0){

}
複製代碼

2.不建議修改變量所保存值的類型

變量是鬆散類型的,所謂鬆散類型就是能夠用來保存任何類型的數據。換句話說, 每一個變量僅僅是一個用於保存值的佔位符而已;以下代碼:dom

var message = "hi"; 
複製代碼

像這樣初始化變量並不會把它標記爲字符串類型; 初始化的過程就是給變量賦一個值那麼簡單。所以,能夠在修改變量值的同時修改值的類型:編程語言

var message = "hi"; 
message = 100;         // 有效,但不推薦 
複製代碼

這樣給人的感受就過於隨意了,且可讀性太差,同時,js引擎在進行編譯的時候也須要額外的耗時,不利於性能。推薦的方式是在初始化變量的時候給變量一個默認值:ide

var message = "hi",
    found = false,     
    age = 29
複製代碼

3.避免延長做用域鏈

在兩種狀況下會發生做用域鏈的延長:函數

  • try-catch 語句的 catch 塊;
  • with 語句

這兩個語句都會在做用域鏈的前端添加一個變量對象。對 with 語句來講,會將指定的對象添加到 做用域鏈中。對 catch 語句來講,會建立一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明。

咱們知道,標識符解析是沿着做用域鏈一級一級地搜索標識符的過程。搜索過程始終從做用域鏈的前端開始, 而後逐級地向後回溯,直至找到標識符爲止,所以做用域鏈越長,查找越慢。

4.緩存變量

好比數組長度:

for (let j = 0; j < area.geo.length; j++) {
     
 }
複製代碼

應該寫到一個變量裏,避免每次循環都去查找這個對象且計算長度

let geoLength = area.geo.length
for (let j = 0; j < geoLength; j++) {
     
 }
複製代碼

另外,緩存變量能夠進行dom的優化:

let odiv=document.getElementById('content');
//接下來是一些操做dom的代碼。。。
複製代碼

這樣避免了屢次去查找dom元素,能夠提升代碼效率。

5.關於if語句

大多數編程語言中爲經常使用的一個語句就是 if 語句,這裏提三點建議:

(1)始終使用代碼塊

業界廣泛推崇的佳實踐是始終使用代碼塊,即便要執行的只有一行代碼。由於這樣能夠消 除人們的誤解,不然可能讓人分不清在不一樣條件下要執行哪些語句。

if (i > 25)    
alert("Greater than 25.");             // 單行語句 
else {     
alert("Less than or equal to 25.");    // 代碼塊中的語句 
} 
 
複製代碼

(2)用三目運算符取代簡單的 if-else

好比一個簡單的函數:

lightBackground () {
      if(this.mode === 'dark'){
          return normal
      }else {
           return light
      }
    }
複製代碼

用三目運算符來寫就不會顯得很臃腫,給人的感受很清晰

lightBackground () {
      return this.mode === 'dark' ? 'normal' : 'light'
    }
複製代碼

原來的五行代碼如今須要一行就OK了,代碼的執行效率也比以前的要高。

(3)優化嵌套的條件語句

好比有大量的if-else語句:

if (index === 0) {
       fn0();
      } else if (index === 1) {
        fn1();
      } else if (index === 2) {
        fn2();
      } else if (index === 3) {
        fn3();
      }
複製代碼

能夠用switch語句來優化代碼。從根本上講,switch 語句就是爲了讓開發人員免於編寫像上面這樣的代碼。

switch(index){
    case 0:
    fn0();
    break;
    case 1:
    fn(1);
    break;
    case 2:
    fn2();
    break;
    case 3:
    fn3();
    break;
    default:
    fn()
}
複製代碼

或者使用對象的方法替代:

let idxObj = {
    0: fn0,
    1: fn1,
    2: fn2,
    3: fn3,
    4: fn
}
if(num in idxObj){
    idxObj[num]()
}
複製代碼

6.巧用短路操做符

邏輯或和邏輯與的操做屬於短路操做,即若是第一個操做數可以決定結果,那麼就不會再對第二個操做數求值。

(1)咱們能夠利用邏輯或的這一行爲來避免爲變量賦 null 或 undefined 值。

例如:

const hmsr = this.$route.query.hmsr || query.hmsr || ''
複製代碼

ECMAScript程序的賦值語句常常會使用這種模式。

(2)邏輯與能夠避免調用undefined的屬性時報錯

watch: {
    carList (to) {
      this.swiper && this.swiper.slideTo(0)
    },
  },
複製代碼

7.函數的優化

在JavaScript開發中,大多時候都離不開函數,關於函數,提如下幾點建議:

(1)函數的命名

函數名應該以動詞開始,如 getName()。返回布爾類型值的函數通常以 is 開頭,如 isEnable()。

(2)明確函數的返回類型

好比這樣的代碼:

function getPrice(num){
    if(num < 0) return "";
    else return num * 20;
}
複製代碼

這個函數有時候返回空字符串,有的時候又會返回整數。這樣寫雖然不會報錯,可是有可能爲後邊的代碼埋下隱患。假如你一不當心進行了運算,返回字符串的狀況你就獲得了NaN,o(╯□╰)o。。 推薦的寫法是:

function getPrice(num){
    if(num < 0) return -1;
    else return num * 20;
}
複製代碼

這樣寫避免了一些沒必要要的錯誤,也使這個函數更清晰,不會讓人疑惑。

(3)關於函數的參數

實際開發中,向函數傳遞參數是不可避免的,可是若是一個函數要傳一大串的參數,那這看起來是很是恐怖的,使用這個函數的人不但要搞懂每一個參數的意義,並且要對號入座不能出一點差錯。

因此咱們應該將函數的參數儘量的減小,能夠把參數都放入一個對象內,而後把該對象傳函數

8.ES6的一些使用

代碼中ES6的使用可讓你的代碼更簡潔,固然是有不少的了。這裏列幾個平時比較經常使用的:

(1)反引號(`)

模板字符串(template string)是加強版的字符串,用反引號(`)標識。它能夠看成普通字符串使用,也能夠用來定義多行字符串,或者在字符串中嵌入變量。

傳統的 JavaScript 語言,輸出模板一般是這樣寫的:

citys="<li value="+item.xzqh+">"+item.name+"</li>";  
複製代碼

模板字符串中嵌入變量,須要將變量名寫在${}之中。

citys=`<li value="${xzqh}">${name}</li>`; 
複製代碼

使用模板字符串表示多行字符串,全部的空格和縮進都會被保留在輸出之中。

$('#list').html(`
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`);
複製代碼

上面代碼中,全部模板字符串的空格和換行,都是被保留的,好比ul標籤前面會有一個換行。

(2)箭頭函數

箭頭函數使得表達更加簡潔。

const isEven = n => n % 2 === 0;
const square = n => n * n;
複製代碼

上面代碼只用了兩行,就定義了兩個簡單的工具函數。若是不用箭頭函數,可能就要佔用多行,並且還不如如今這樣寫醒目。

箭頭函數的一個用處是簡化回調函數。

// 正常函數寫法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭頭函數寫法
[1,2,3].map(x => x * x);
複製代碼

Java用->箭頭,C#用的箭頭與JS同樣:=>,這個箭頭叫「lambda運算符」.

lambda表達式(箭頭函數)聽說是定義函數最簡潔的方法,語法上幾乎沒有冗餘成分了。由於JS弱類型的特色,JS中的lambda表達式要比C#和Java中的更簡潔。

(3)使用 ES6 的 class

雖然 ES6 的 class 和使用 function 的 prototype 原理上是沒有區別的,都是用的原型。class 能夠經過extends關鍵字實現繼承,這比經過修改原型鏈實現繼承,要清晰和方便不少。

好比:

function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.addAge = function(){
    this.age++;
};

Person.prototype.setName = function(name){
    this.name = name;
};
複製代碼

使用class的話代碼就看起來簡潔易懂了

class Person{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    addAge(){
        this.age++;
    }
    setName(name){
        this.name = name;
    }
}
複製代碼

總結

以上就是一些讓代碼看起來更優雅的建議,固然不只僅是看起來優雅而已,有時候你隨手寫的一兩句代碼可能就會對性能形成不一樣的影響,可大可小。因此這裏仍是建議你們按照必定的規範來寫,更簡潔高效的代碼不只僅是我的能力的一種體現,你的團隊也須要寫出你來寫出優雅高效的代碼來提升團隊的總體效率。

關注咱們

公衆號@前端論道
相關文章
相關標籤/搜索