20個JS優化代碼技巧

原文網址連接爲:http://www.jstips.co/ 。截取了一部分本人認爲比較實用的技巧分享給你們。其中一小部分技巧爲JS面向對象的寫法,不宜一一列出。關於JS面向對象的寫法可參考本人前幾篇隨筆:javascript

JS面向對象(1) -- 簡介,入門,系統經常使用類,自定義類,constructor,typeof,instanceof,對象在內存中的表現形式html

JS面向對象(2) -- this的使用,對象之間的賦值,for...in語句,delete使用,成員方法,json對象的使用,prototype的使用,原型繼承與原型鏈java

JS面向對象(3) -- Object類,靜態屬性,閉包,私有屬性, call和apply的使用,繼承的三種實現方法程序員

 

1.Insert item inside an Array(向數組中插入元素)json

向一個數組中插入元素是平時很常見的一件事情。你可使用push在數組尾部插入元素,能夠用unshift在數組頭部插入元素,也能夠用splice在數組中間插入元素。數組

 1  var arr = [1,2,3,4,5];
 2  //old method
 3  arr.push(6); 4 //new method 快43% 5 arr[arr.length] = 6; 6 7 var arr = [1,2,3,4,5]; 8 //old method 9 arr.unshift(0); 10 //new method 快98% 11 [0].concat(arr);

 

2.Improve Nested Conditionals(優化嵌套的條件語句) 閉包

面對大量的if-else語句app

 1  //method1
 2      if (color) {
 3          if (color === 'black') { 4  printBlackBackground(); 5 } else if (color === 'red') { 6  printRedBackground(); 7 } else if (color === 'blue') { 8  printBlueBackground(); 9 } else if (color === 'green') { 10  printGreenBackground(); 11 } else { 12  printYellowBackground(); 13  } 14  } 15 16 //method2 17 switch(color) { 18 case 'black': 19  printBlackBackground(); 20 break; 21 case 'red': 22  printRedBackground(); 23 break; 24 case 'blue': 25  printBlueBackground(); 26 break; 27 case 'green': 28  printGreenBackground(); 29 break; 30 default: 31  printYellowBackground(); 32  } 33 34 //method3 35 switch(true) { 36 case (typeof color === 'string' && color === 'black'): 37  printBlackBackground(); 38 break; 39 case (typeof color === 'string' && color === 'red'): 40  printRedBackground(); 41 break; 42 case (typeof color === 'string' && color === 'blue'): 43  printBlueBackground(); 44 break; 45 case (typeof color === 'string' && color === 'green'): 46  printGreenBackground(); 47 break; 48 case (typeof color === 'string' && color === 'yellow'): 49  printYellowBackground(); 50 break; 51  } 52 53 //method4 54 var colorObj = { 55 'black': printBlackBackground, 56 'red': printRedBackground, 57 'blue': printBlueBackground, 58 'green': printGreenBackground, 59 'yellow': printYellowBackground 60  }; 61 if (color in colorObj) { 62  colorObj[color](); 63 }

 

3.Sorting strings with accented characters(排列含音節字母的字符串)異步

Javascript有一個原生方法sort能夠排列數組。一次簡單的array.sort()將每個數組元素視爲字符串並按照字母表排列。可是當你試圖整理一個非ASCII元素的數組時,你可能會獲得一個奇怪的結果。jsp

 1      ['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort();
 2      // ["Buenos Aires", "Mumbai", "New York", "Shanghai"]
 3      
 4  //method1
 5      // 西班牙語
 6      ['único','árbol', 'cosas', 'fútbol'].sort(); 7 // ["cosas", "fútbol", "árbol", "único"] // bad order 8 // 德語 9 ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); 10 // ["Wann", "Woche", "wäre", "wöchentlich"] // bad order 11 12 //method2 13 ['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare); 14 // ["árbol", "cosas", "fútbol", "único"] 15 16 ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare); 17 // ["Wann", "wäre", "Woche", "wöchentlich"]

 

4.Differences between undefined and null(undefined與null的區別

  • undefined表示一個變量沒有被聲明,或者被聲明瞭但沒有被賦值

  • null是一個表示「沒有值」的值

  • Javascript將未賦值的變量默認值設爲undefined

  • Javascript歷來不會將變量設爲null。它是用來讓程序員代表某個用var聲明的變量時沒有值的。

  • undefined不是一個有效的JSON,而null

  • undefined的類型(typeof)是undefined

  • null的類型(typeof)是object

  • 它們都是基本類型

  • null === undefined // false

 

5.Check if a property is in a Object(檢查某對象是否有某屬性)

 1  //method1
 2      var myObject = {
 3        name: '@tips_js'
 4  }; 5 if (myObject.name) { } 6 7 //method2 8 var myObject = { 9 name: '@tips_js' 10  }; 11 12 myObject.hasOwnProperty('name'); // true 13 'name' in myObject; // true 14 15 myObject.hasOwnProperty('valueOf'); // false, valueOf 繼承自原型鏈 16 'valueOf' in myObject; // true

二者檢查屬性的深度不一樣,換言之hasOwnProperty只在自己有此屬性時返回true,而in操做符不區分屬性來自於自己或繼承自原型鏈。

 

6.Tip to measure performance of a javascript block(測量javascript代碼塊性能的小知識)

快速的測量javascript的性能,咱們可使用console的方法,例如 

1  console.time("Array initialize");
2  var arr = new Array(100), 3 len = arr.length, 4  i; 5 6 for (i = 0; i < len; i++) { 7 arr[i] = new Object(); 8  }; 9 console.timeEnd("Array initialize"); // 0.711ms

 

7.Fat Arrow Functions(箭頭函數)

語法: 更少的代碼行; 再也不須要一遍一遍的打function

語義: 從上下文中捕獲this關鍵字

 1  // 使用functions
 2  var arr = [5,3,2,9,1];
 3  var arrFunc = arr.map(function(x) { 4 return x * x; 5  }); 6  console.log(arrFunc ) 7 8 // 使用箭頭函數 9 var arr = [5,3,2,9,1]; 10 var arrFunc = arr.map((x) => x*x); 11 console.log(arrFunc )

箭頭函數在這種狀況下省去了寫小括號,function以及return的時間。

 

8.Even simpler way of using indexOf as a contains clause(更簡單的使用indexOf實現contains功能)

JavaScript並未提供contains方法。檢測子字符串是否存在於字符串或者變量是否存在於數組你可能會這樣作。

1  var someText = 'javascript rules';
2  if (someText.indexOf('javascript') !== -1) { 3  } 4 5 // or 6 if (someText.indexOf('javascript') >= 0) { 7 }

建議的方法:

1  var someText = 'text';
2  !!~someText.indexOf('tex'); // someText contains "tex" - true
3  !~someText.indexOf('tex'); // someText NOT contains "tex" - false
4  ~someText.indexOf('asd'); // someText doesn't contain "asd" - false
5  ~someText.indexOf('ext'); // someText contains "ext" - true

 

9.Rounding the fast way(更快的取整)

一個位操做符 ~ 將輸入的32位的數字(input)轉換爲 -(input+1). 兩個位操做符將輸入(input)轉變爲 -(-(input + 1)+1) 是一個使結果趨向於0的取整好工具. 對於數字, 負數就像使用Math.ceil()方法而正數就像使用Math.floor()方法. 轉換失敗時,返回0,這在Math.floor()方法轉換失敗返回NaN時或許會派上用場。

 1  // 單個 ~
 2  console.log(~1337)    // -1338
 3  
 4  // 數字輸入
 5  console.log(~~47.11)  // -> 47
 6  console.log(~~-12.88) // -> -12
 7  console.log(~~1.9999) // -> 1
 8  console.log(~~3)      // -> 3
 9  
10  // 轉換失敗
11  console.log(~~[]) // -> 0
12  console.log(~~NaN)  // -> 0
13  console.log(~~null) // -> 0
14  
15  // 大於32位整數時轉換失敗
16  console.log(~~(2147483647 + 1) === (2147483647 + 1)) // -> 0

 

10.Safe string concatenation

 1  //method 1
 2  var one = 1;
 3  var two = 2; 4 var three = '3'; 5 var result = ''.concat(one, two, three); //"123" 6 //method 2 7 var one = 1; 8 var two = 2; 9 var three = '3'; 10 var result = one + two + three; //"33" instead of "123"

拼接時使用加號,可能會致使意想不到的錯誤結果。

 

11.Return objects to enable chaining of functions(返回對象,使方法能夠鏈式調用)

 1  function Person(name) {
 2    this.name = name; 3 4 this.sayName = function() { 5 console.log("Hello my name is: ", this.name); 6 return this; 7  }; 8 9 this.changeName = function(name) { 10 this.name = name; 11 return this; 12  }; 13  } 14 15 var person = new Person("John"); 16 person.sayName().changeName("Timmy").sayName();

 在面向對象的Javascript中爲對象創建一個方法時,返回當前對象可讓你在一條鏈上調用方法。

 

12.Converting to number fast way(轉換爲數字的更快方法)

將字符串轉換爲數字是極爲常見的。最簡單和快速的方法是使用+(加號) 來實現。

1  var one = '1';
2  var numberOne = +one; // Number 1
3  var one = '1'; 4 var negativeNumberOne = -one; // Number -1

  

13.Use === instead of ==(使用 === 而不是 ==)

== (或者 !=) 操做在須要的狀況下自動進行了類型轉換。=== (或 !==)操做不會執行任何轉換。===在比較值和類型時,能夠說比==更快。

 1  [10] ==  10      // 爲 true
 2  [10] === 10      // 爲 false
 3  
 4  '10' ==  10      // 爲 true
 5  '10' === 10      // 爲 false
 6  
 7   []  ==  0       // 爲 true
 8   []  === 0       // 爲 false
 9  
10   ''  ==  false   // 爲 true 但 true == "a" 爲false
11   ''  === false   // 爲 false 

 

14.Filtering and Sorting a List of Strings(過濾並排序字符串列表)

你可能有一個不少名字組成的列表,須要過濾掉重複的名字並按字母表將其排序。

1  var keywords = ['do', 'if', 'in', 'for', 'new', 'try', 'var', 'case', 'else', 'enum', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'delete', 'export', 'import', 'return', 'switch', 'typeof', 'default', 'extends', 'finally', 'continue', 'debugger', 'function', 'do', 'if', 'in', 'for', 'int', 'new', 'try', 'var', 'byte', 'case', 'char', 'else', 'enum', 'goto', 'long', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'final', 'float', 'short', 'super', 'throw', 'while', 'delete', 'double', 'export', 'import', 'native', 'public', 'return', 'static', 'switch', 'throws', 'typeof', 'boolean', 'default', 'extends', 'finally', 'package', 'private', 'abstract', 'continue', 'debugger', 'function', 'volatile', 'interface', 'protected', 'transient', 'implements', 'instanceof', 'synchronized', 'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch', 'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger', 'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof', 'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'await', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch', 'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger', 'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof'];
2  var filteredAndSortedKeywords = keywords 3 .filter(function (keyword, index) { 4 return keywords.lastIndexOf(keyword) === index; 5  }) 6 .sort(function (a, b) { 7 return a < b ? -1 : 1; 8 });

 由於咱們不想改變咱們的原始列表,因此咱們準備用高階函數叫作filter,它將基於咱們傳遞的回調方法返回一個新的過濾後的數組。回調方法將比較當前關鍵字在原始列表裏的索引和新列表中的索引,僅當索引匹配時將當前關鍵字push到新數組。

最後咱們準備使用sort方法排序過濾後的列表,sort只接受一個比較方法做爲參數,並返回按字母表排序後的列表。

1  const filteredAndSortedKeywords = keywords
2   .filter((keyword, index) => keywords.lastIndexOf(keyword) === index) 3 .sort((a, b) => a < b ? -1 : 1); 4  console.log(filteredAndSortedKeywords); 5 // ['abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield']

 

15.Short circuit evaluation in JS(JS中的短路求值)

短路求值是說, 只有當第一個運算數的值沒法肯定邏輯運算的結果時,纔對第二個運算數進行求值:當AND(&&)的第一個運算數的值爲false時,其結果一定爲false;當OR(||)的第一個運算數爲true時,最後結果一定爲true。

邏輯或能夠用來給參數設置默認值。

1  function theSameOldFoo(name){
2      name = name || 'Bar' ; 3 console.log("My best friend's name is " + name); 4  } 5 theSameOldFoo(); // My best friend's name is Bar 6 theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar

 邏輯與能夠用來避免調用undefined參數的屬性時報錯

 1  var dog = {
 2    bark: function(){ 3 console.log('Woof Woof'); 4  } 5  }; 6 // 調用 dog.bark(); 7 dog.bark(); // Woof Woof. 8 // 可是當dog未定義時,dog.bark() 將會拋出"Cannot read property 'bark' of undefined." 錯誤 9 // 防止這種狀況,咱們可使用 &&. 10 dog&&dog.bark(); // This will only call dog.bark(), if dog is defined.

 

16.!!(!!)

 1  !!"" // false
 2  !!0 // false
 3  !!null // false
 4  !!undefined // false
 5  !!NaN // false
 6  
 7  !!"hello" // true
 8  !!1 // true
 9  !!{} // true
10  !![] // true

 

17.Avoid modifying or passing arguments into other functions — it kills optimization(避免修改和傳遞arguments給其餘方法 — 影響優化)

在JavaScript的方法裏,arguments參數可讓你訪問傳遞給該方法的全部參數。arguments是一個類數組對象;arguments但是使用數組標記訪問,並且它有length參數,可是它沒有filter, map, forEach這樣內建到數組內的方法。所以,以下代碼是一個很是常見的將arguments轉換爲數組的辦法:

1 var args = Array.prototype.slice.call(arguments);
2 //或者
3 var args = [].slice.call(arguments);

不幸的是,傳遞arguments給任何參數,將致使Chrome和Node中使用的V8引擎跳過對其的優化,這也將使性能至關慢。因此,正確的作法只有:

1 var args = new Array(arguments.length);
2     for(var i = 0; i < args.length; ++i) { 3 args[i] = arguments[i]; 4 }

 

18.Implementing asynchronous loop(實現異步循環)

試着寫一個異步方法,每秒打印一次循環的索引值。

1 for (var i=0; i<5; i++) {
2     setTimeout(function(){ 3  console.log(i); 4 }, 1000); 5 } 

但輸出的結果會是5,5,5,5,5。這明顯是有問題的,緣由是:每次時間結束(timeout)都指向原始的i,而並不是它的拷貝。因此,for循環使i增加到5,以後timeout運行並調用了當前i的值(也就是5)。

解決的辦法是:有幾個不一樣的方式能夠拷貝i。最普通且經常使用方法是經過聲明函數來創建一個閉包,並將i傳給此函數。咱們這裏使用了自調用函數。

1 for (var i=0; i<5; i++) {
2     (function(num){ 3 setTimeout(function(){ 4  console.log(num); 5 }, 1000); 6  })(i); 7 } 

 

19.Flattening multidimensional Arrays in JavaScript(Javascript多維數組扁平化)

測試地址:http://jsperf.com/flatten-an-array-loop-vs-reduce/6

 

 

20.Using JSON.Stringify(使用JSON.Stringify)

加入有一個對象具備參數"prop1", "prop2", "prop3"。 咱們能夠經過傳遞 附加參數 給 JSON.stringify 來選擇性將參數生成字符串,像這樣:

 1 var obj = {
 2     'prop1': 'value1', 3 'prop2': 'value2', 4 'prop3': 'value3' 5 }; 6 7 var selectedProperties = ['prop1', 'prop2']; 8 9 var str = JSON.stringify(obj, selectedProperties); 10 11 // str 12 // {"prop1":"value1","prop2":"value2"}
相關文章
相關標籤/搜索