91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS編寫優化的技巧有哪些

發布時間:2021-11-03 14:37:27 來源:億速云 閱讀:114 作者:iii 欄目:web開發

本篇內容主要講解“JS編寫優化的技巧有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JS編寫優化的技巧有哪些”吧!

1. 按強類型風格寫代碼

JS 是弱類型的,但是寫代碼的時候不能太隨意,寫得太隨意也體現了編碼風格不好。下面分點說明:

(1)定義變量的時候要指明類型,告訴 JS 解釋器這個變量是什么數據類型的,而不要讓解釋器去猜,例如不好的寫法:

var num,     str,     obj;

聲明了三個變量,但其實沒什么用,因為解釋器不知道它們是什么類型的,好的寫法應該是這樣的:

var num = 0,     str = '',     obj = null;

定義變量的時候就給他一個默認值,這樣不僅方便了解釋器,也方便了閱讀代碼的人,他會在心里有數——知道這些變量可能會當作什么用。

(2)不要隨意地改變變量的類型,例如下面代碼:

var num = 5; num = "-" + num;

第 1 行它是一個整型,第 2 行它變成了一個字符串。因為 JS  最終都會被解釋成匯編的語言,匯編語言變量的類型肯定是要確定的,你把一個整型的改成了字符串,那解釋器就得做一些額外的處理。并且這種編碼風格是不提倡的,有一個變量第  1 行是一個整型,第 10 行變成了一個字符串,第 20 行又變成了一個  object,這樣就讓閱讀代碼的人比較困惑,上面明明是一個整數,怎么突然又變成一個字符串了。好的寫法應該是再定義一個字符串的變量:

var num = 5; var sign = "-" + num;

(3)函數的返回類型應該是要確定的,例如下面不確定的寫法:

function getPrice(count){     if(count < 0) return "";     else return count * 100; }

getPrice 這個函數有可能返回一個整數,也有可能返回一個空的字符串。這樣寫也不太好,雖然它是符合 JS  語法的,但這種編碼風格是不好的。使用你這個函數的人會有點無所適從,不敢直接進行加減乘除,因為如果返回字符串進行運算的話值就是 NaN  了。函數的返回類型應該是要確定的,如下面是返回整型:

function getPrice(count){     if(count < 0) return -1;     else return count * 100; }

然后告訴使用者,如果返回-1 就表示不合法。如果類型確定,解釋器也不用去做一些額外的工作,可以加快運行速度。

2. 減少作用域查找

(1)不要讓代碼暴露在全局作用域下

例如以下運行在全局作用域的代碼:

<script>     var map = document.querySelector("#my-map");     map.style.height = "600px"; </script>

有時候你需要在頁面直接寫一個 script,要注意在一個 script  標簽里面,代碼的上下文都是全局作用域的,由于全局作用域比較復雜,查找比較慢。例如上面的 map 變量,第二行在使用的時候,需要在全局作用域查找一下這個變量,假設  map 是在一個循環里面使用,那可能就會有效率問題了。所以應該要把它搞成一個局部的作用域:

<script> !function(){     var map = document.querySelector("#my-map");     map.style.height = "600px"; }() </script>

上面用了一個 function 制造一個局部作用域,也可以用 ES6 的塊級作用域。由于 map  這個變量直接在當前的局部作用域命中了,所以就不用再往上一級的作用域(這里是全局作用域)查找了,而局部作用域的查找是很快的。同時直接在全局作用域定義變量,會污染  window 對象。

(2)不要濫用閉包

閉包的作用在于可以讓子級作用域使用它父級作用域的變量,同時這些變量在不同的閉包是不可見的。這樣就導致了在查找某個變量的時候,如果當前作用域找不到,就得往它的父級作用域查找,一級一級地往上直到找到了,或者到了全局作用域還沒找到。因此如果閉包嵌套得越深,那么變量查找的時間就越長。如下:

function getResult(count){     count++;     function process(){         var factor = 2;         return count * factor - 5;     }     return process(); }

上面的代碼定義了一個 process 函數,在這個函數里面 count 變量的查找時間要高于局部的 factor 變量。其實這里不太適合用閉包,可以直接把  count 傳給 process:

function getResult(count){     count++;     function process(count){         var factor = 2;         return count * factor - 5;     }     return process(count); }

這樣 count 的查找時間就和 factor  一樣,都是在當前作用域直接命中。這個就啟示我們如果某個全局變量需要頻繁地被使用的時候,可以用一個局部變量緩存一下,如下:

var url = ""; if(window.location.protocal === "https:"){     url = "wss://xxx.com" + window.location.pathname + window.location.search; }

頻繁地使用了 window.location 對象,所以可以先把它緩存一下:

var url = ""; var location = window.location; if(location.protocal === "https:"){     url = "wss://xxx.com" + location.pathname + location.search; }

搞成了一個局變變量,這樣查找就會明顯快于全局的查找,代碼也可以寫少一點。

3.避免==的使用

這里你可能會有疑問了,有些人喜歡用==,有些人喜歡用===,大家的風格不一樣,你為什么要強制別人用===呢?習慣用==的人,不能僅僅是因為==比===少敲了一次鍵盤。為什么不提倡用==呢?

(1)如果你確定了變量的類型,那么就沒必要使用==了,如下:

if(typeof num != "undefined"){  } var num = parseInt(value); if(num == 10){  }

上面的兩個例子都是確定類型的,一個是字符串,一個是整數。就沒必要使用==了,直接用===就可以了。

(2)如果類型不確定,那么應該手動做一下類型轉換,而不是讓別人或者以后的你去猜這里面有類型轉換,如下:

var totalPage = "5"; if(parseInt(totalPage) === 1){  }

(3)使用==在 JSLint 檢查的時候是不通過的:

if(a == b){  }

如下 JSLint 的輸出:

Expected &lsquo;===&rsquo; and instead saw &lsquo;==&rsquo;. if(a == b){

(4)并且使用==可能會出現一些奇怪的現象,這些奇怪的現象可能會給代碼埋入隱患:

null == undefined          //true '' == '0'                  //false 0  == ''                   //true 0  == '0'                  //true '  ' == 0            //true new String("abc") == "abc" //true new Boolean(true) == true  //true true == 1                  //true

上面的比較在用===的時候都是 false,這樣才是比較合理的。例如第一點 null 居然會等于 undefined,就特別地奇怪,因為 null 和  undefined 是兩個毫無關系的值,null 應該是作為初始化空值使用,而 undefined 是用于檢驗某個變量是否未定義。這和第 1  點介紹強類型的思想是相通的。

4. 合并表達式

如果用 1 句代碼就可以實現 5 句代碼的功能,那往往 1 句代碼的執行效率會比較高,并且可讀性可能會更好

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

如上面的 getPrice 函數:

function getPrice(count){     if(count < 0) return -1;     else return count * 100; }

可以改成:

function getPrice(count){     return count < 0 ? return -1 : count * 100; }

這個比寫一個 if-else 看起來清爽多了。當然,如果你寫了 if-else,壓縮工具也會幫你把它改三目運算符的形式:

function getPrice(e){return 0>e?-1:100*e}

(2)連等

連等是利用賦值運算表達式會返回所賦的值,并且執行順序是從右到左的,如下:

overtime = favhouse = listingDetail = {...}

有時候你會看到有人這樣寫:

var age = 0; if((age = +form.age.value) >= 18){     console.log("你是成年人"); } else {     consoe.log("小朋友,你還有" + (18 - age) + "就成年了"); }

也是利用了賦值表達式會返回一個值,在 if 里面賦值的同時用它的返回值做判斷,然后 else 里面就已經有值了。上面的+號把字符串轉成了整數。

(3)自增

利用自增也可以簡化代碼。如下,每發出一條消息,localMsgId 就自增 1:

chatService.sendMessage(localMsgId++, msgContent);

5. 減少魔數

例如,在某個文件的第 800 行,冒出來了一句:

dialogHandler.showQuestionNaire("seller", "sell", 5, true);

就會讓人很困惑了,上面的四個常量分別代表什么呢,如果我不去查一個那個函數的變量說明就不能夠很快地意會到這些常量分別有什么用。這些意義不明的常量就叫“魔數”。所以最好還是給這些常量取一個名字,特別是在一些比較關鍵的地方。例如上面的代碼可改成:

var naireType = "seller",     dialogType = "sell",     questionsCount = 5,     reloadWindow = true;  naireHandler.showNaire(naireType, dialogType, questionsCount, reloadWindow);

這樣意義就很明顯了。

6. 使用 ES6 簡化代碼

ES6 已經發展很多年了,兼容性也已經很好了。恰當地使用,可以讓代碼更加地簡潔優雅。

(1)使用箭頭函數取代小函數

有很多使用小函數的場景,如果寫個 function,代碼起碼得寫 3 行,但是用箭頭函數一行就搞定了,例如實現數組從大到小排序:

var nums = [4, 8, 1, 9, 0]; nums.sort(function(a, b){     return b - a; }); //輸出[9, 8, 4, 1, 0]

如果用箭頭函數,排序只要一行就搞定了:

var nums = [4, 8, 1, 9, 0];``nums.sort(a, b => b - a);

代碼看起來簡潔多了,還有 setTimeout 里面經常會遇到只要執行一行代碼就好了,寫個 function  總感覺有點麻煩,用字符串的方式又不太好,所以這種情況用箭頭函數也很方便:

setTimeout(() => console.log("hi"), 3000)

箭頭函數在 C++/Java 等其它語言里面叫做 Lambda 表達式,Ruby 比較早就有這種語法形式了,后來 C++/Java  也實現了這種語法。當然箭頭函數或者 Lambda 表達式不僅適用于這種一行的,多行代碼也可以,不過在一行的時候它的優點才比較明顯。

(2)使用 ES6 的 class

雖然 ES6 的 class 和使用 function 的 prototype 本質上是一樣的,都是用的原型。但是用 class  可以減少代碼量,同時讓代碼看起來更加地高大上,使用 function 要寫這么多:

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;     } }

并且 class 還可以很方便地實現繼承、靜態的成員函數,就不需要自己再去通過一些技巧去實現了。

(3)字符串拼接

以前要用+號拼接:

var tpl =     '<div>' +     '    <span>1</span>' +     '</div>';

現在只要用兩個反引號“`”就可以了:

var tpl = `   <div>         <span>1</span>     </div> `;

另外反引號還支持占位替換,原本你需要:

var page = 5,     type = encodeURIComponet("#js"); var url = "/list?page=" + page + "&type=" + type;

現在只需要:

var url = `/list?page=${page}&type=${type}`;

就不用使用+號把字符串拆散了。

(4)塊級作用域變量

塊級作用域變量也是 ES6 的一個特色,下面的代碼是一個任務隊列的模型抽象:

var tasks = []; for(var i = 0; i < 4; i++){     tasks.push(function(){         console.log("i is " + i);     }); } for(var j = 0; j < tasks.length; j++){     tasks[j](); }

但是上面代碼的執行輸出是 4,4,4,4,并且不是想要輸出:0,1,2,3,所以每個 task 就不能取到它的 index 了,這是因為閉包都是用的同一個  i 變量,i 已經變成 4 了,所以執行閉包的時候就都是 4 了。那怎么辦呢?可以這樣解決:

var tasks = []; for(var i = 0; i < 4; i++){     !function(k){         tasks.push(function(){             console.log("i is " + k);         });     }(i); } for(var j = 0; j < tasks.length; j++){     tasks[j](); }

把 i 賦值給了 k,由于 k 它是一個 function 的一個參數,每次執行函數的時候,肯定會實例化新的 k,所以每次的 k  都是不同的變量,這樣就輸出就正常了。但是代碼看起來有點別扭,如果用 ES6,只要把 var 改成 let 就可以了:

var tasks = []; for(let i = 0; i <= 4; i++){     tasks.push(function(){         console.log("i is " + i);     }); } for(var j = 0; j < tasks.length; j++){     tasks[j](); }

只改動了 3 個字符就達到了目的。因為 for 循環里面有個大括號,大括號就是一個獨立的作用域,let  定義的變量在獨立的作用域里面它的值也是獨立的。當然即使沒寫大括號 for 循環執行也是獨立的。除了以上幾點,ES6 還有其它一些比較好用的功能,如 Object的 assign,Promise 等,也是可以幫助寫出簡潔高效的代碼。

到此,相信大家對“JS編寫優化的技巧有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

js
AI

萍乡市| 宁陕县| 南郑县| 德州市| 泗水县| 永清县| 金阳县| 突泉县| 西充县| 浠水县| 达尔| 诏安县| 洱源县| 灌阳县| 略阳县| 论坛| 岚皋县| 和平区| 丹东市| 铜陵市| 石首市| 钟祥市| 新昌县| 巴彦县| 东港市| 银川市| 清镇市| 合作市| 苍溪县| 永城市| 潜山县| 马边| 双牌县| 泸溪县| 调兵山市| 昆山市| 江北区| 珠海市| 东宁县| 荥经县| 高邮市|