45種Javascript技巧大全

来源:http://www.cnblogs.com/Ajatar/archive/2016/06/23/5611654.html
-Advertisement-
Play Games

JavaScript是一個絕冠全球的編程語言,可用於Web開發、移動應用開發(PhoneGap、Appcelerator)、伺服器端開發(Node.js和Wakanda)等等。JavaScript還是很多新手踏入編程世界的第一個語言。既可以用來顯示瀏覽器中的簡單提示框,也可以通過nodebot或no ...


JavaScript是一個絕冠全球的編程語言,可用於Web開發、移動應用開發(PhoneGap、Appcelerator)、伺服器端開發(Node.js和Wakanda)等等。JavaScript還是很多新手踏入編程世界的第一個語言。既可以用來顯示瀏覽器中的簡單提示框,也可以通過nodebot或nodruino來控制機器人。能夠編寫結構清晰、性能高效的JavaScript代碼的開發人員,現如今已成了招聘市場最受追捧的人。

  在這篇文章里,我將分享一些JavaScript的技巧、秘訣和最佳實踐,除了少數幾個外,不管是瀏覽器的JavaScript引擎,還是伺服器端JavaScript解釋器,均適用。

    本文中的示例代碼,通過了在Google Chrome 30最新版(V8 3.20.17.15)上的測試。

1、首次為變數賦值時務必使用var關鍵字

      變數沒有聲明而直接賦值得話,預設會作為一個新的全局變數,要儘量避免使用全局變數。

2、使用===取代==

      ==和!=操作符會在需要的情況下自動轉換數據類型。但===和!==不會,它們會同時比較值和數據類型,這也使得它們要比==和!=快。

      [10] === 10 // is false

      [10] == 10 // is true

      '10' == 10 // is true

      '10' === 10 // is false

       [] == 0 // is true

       [] === 0 // is false

       '' == false // is true but true == "a" is false

       '' === false // is false

3、underfined、null、0、false、NaN、空字元串的邏輯結果均為false

4、行尾使用分號

      實踐中最好還是使用分號,忘了寫也沒事,大部分情況下JavaScript解釋器都會自動添加。對於為何要使用分號,可參考文章JavaScript中關於分號的真相。

5、使用對象構造器

      function Person(firstName, lastName){

        this.firstName = firstName;

        this.lastName = lastName;

      }

      var Saad = new Person("Saad", "Mousliki");

6、小心使用typeof、instanceof和contructor

    typeof:JavaScript一元操作符,用於以字元串的形式返回變數的原始類型,註意,typeof null也會返回object,大多數的對象類型(數組Array、時間Date等)也會返回object

    contructor:內部原型屬性,可以通過代碼重寫

    instanceof:JavaScript操作符,會在原型鏈中的構造器中搜索,找到則返回true,否則返回false

    var arr = ["a", "b", "c"];

    typeof arr; // 返回 "object"

    arr instanceof Array // true

    arr.constructor(); //[]

7、使用自調用函數

    函數在創建之後直接自動執行,通常稱之為自調用匿名函數(Self-Invoked Anonymous Function)或直接調用函數表達式(Immediately Invoked Function Expression )。格式如下:

    (function(){

      // 置於此處的代碼將自動執行

    })();

    (function(a,b){

      var result = a+b;

      return result;

    })(10,20)

8、從數組中隨機獲取成員

    var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];

    var randomItem = items[Math.floor(Math.random() * items.length)];

9、獲取指定範圍內的隨機數

    這個功能在生成測試用的假數據時特別有數,比如介與指定範圍內的工資數。

    var x = Math.floor(Math.random() * (max - min + 1)) + min;

10、生成從0到指定值的數字數組

    var numbersArray = [] , max = 100;

    for( var i=1; numbersArray.push(i++) < max;); // numbers = [1,2,3 ... 100]

11、生成隨機的字母數字字元串

    function generateRandomAlphaNum(len) {

      var rdmString = "";

      for( ; rdmString.length < len; rdmString += Math.random().toString(36).substr(2));

      return rdmString.substr(0, len);

    }

12、打亂數字數組的順序

    var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];

    numbers = numbers.sort(function(){ return Math.random() - 0.5});

    /* numbers 數組將類似於 [120, 5, 228, -215, 400, 458, -85411, 122205] */

    這裡使用了JavaScript內置的數組排序函數,更好的辦法是用專門的代碼來實現(如Fisher-Yates演算法),可以參見StackOverFlow上的這個討論。

13、字元串去空格

    Java、C#和PHP等語言都實現了專門的字元串去空格函數,但JavaScript中是沒有的,可以通過下麵的代碼來為String對象函數一個trim函數:

    String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};

    新的JavaScript引擎已經有了trim()的原生實現。

14、數組之間追加

    var array1 = [12 , "foo" , {name "Joe"} , -2458];

    var array2 = ["Doe" , 555 , 100];

    Array.prototype.push.apply(array1, array2);

    /* array1 值為 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

15、對象轉換為數組

    var argArray = Array.prototype.slice.call(arguments);

16、驗證是否是數字

    function isNumber(n){

      return !isNaN(parseFloat(n)) && isFinite(n);

    }

17、驗證是否是數組

    function isArray(obj){

      return Object.prototype.toString.call(obj) === '[object Array]' ;

    }

    但如果toString()方法被重寫過得話,就行不通了。也可以使用下麵的方法:

    Array.isArray(obj); // its a new Array method

    如果在瀏覽器中沒有使用frame,還可以用instanceof,但如果上下文太複雜,也有可能出錯。

    var myFrame = document.createElement('iframe');

    document.body.appendChild(myFrame);

    var myArray = window.frames[window.frames.length-1].Array;

    var arr = new myArray(a,b,10); // [a,b,10]

    // myArray 的構造器已經丟失,instanceof 的結果將不正常

    // 構造器是不能跨 frame 共用的

    arr instanceof Array; // false

18、獲取數組中的最大值和最小值

    var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];

    var maxInNumbers = Math.max.apply(Math, numbers);

    var minInNumbers = Math.min.apply(Math, numbers);

19、清空數組

    var myArray = [12 , 222 , 1000 ];

    myArray.length = 0; // myArray will be equal to [].

20、不要直接從數組中delete或remove元素

    如果對數組元素直接使用delete,其實並沒有刪除,只是將元素置為了undefined。數組元素刪除應使用splice。

    切忌:

      var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];

      items.length; // return 11

      delete items[3]; // return true

      items.length; // return 11

      /* items 結果為 [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */

    而應:

      var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];

      items.length; // return 11

      items.splice(3,1) ;

      items.length; // return 10

      /* items 結果為 [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119]

    刪除對象的屬性時可以使用delete。

21、使用length屬性截斷數組

    前面的例子中用length屬性清空數組,同樣還可用它來截斷數組:

    var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];

    myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

    與此同時,如果把length屬性變大,數組的長度值變會增加,會使用undefined來作為新的元素填充。length是一個可寫的屬性。

    myArray.length = 10; // the new array length is 10

    myArray[myArray.length - 1] ; // undefined

22、在條件中使用邏輯與或

    var foo = 10;

    foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();

    foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

    邏輯或還可用來設置預設值,比如函數參數的預設值。

    function doSomething(arg1){

      arg1 = arg1 || 10; // arg1 will have 10 as a default value if it’s not already set

    }

23、使得map()函數方法對數據迴圈

    var squares = [1,2,3,4].map(function (val) {

      return val * val;

    });

  // squares will be equal to [1, 4, 9, 16]

24、保留指定小數位數

    var num =2.443242342;

    num = num.toFixed(4); // num will be equal to 2.4432

  註意,toFixec()返回的是字元串,不是數字。

25、浮點計算的問題

    0.1 + 0.2 === 0.3 // is false

    9007199254740992 + 1 // is equal to 9007199254740992

    9007199254740992 + 2 // is equal to 9007199254740994

  為什麼呢?因為0.1+0.2等於0.30000000000000004。JavaScript的數字都遵循IEEE 754標準構建,在內部都是64位浮點小數表示,具體可以參見JavaScript中的數字是如何編碼的.

  可以通過使用toFixed()和toPrecision()來解決這個問題。

26、通過for-in迴圈檢查對象的屬性

    下麵這樣的用法,可以防止迭代的時候進入到對象的原型屬性中。

      for (var name in object) {

        if (object.hasOwnProperty(name)) {

        // do something with name

        }

      }

27、逗號操作符

    var a = 0;

    var b = ( a++, 99 );

    console.log(a); // a will be equal to 1

    console.log(b); // b is equal to 99

28、臨時存儲用於計算和查詢的變數

  在jQuery選擇器中,可以臨時存儲整個DOM元素。

    var navright = document.querySelector('#right');

    var navleft = document.querySelector('#left');

    var navup = document.querySelector('#up');

    var navdown = document.querySelector('#down');

29、提前檢查傳入isFinite()的參數

    isFinite(0/0) ; // false

    isFinite("foo"); // false

    isFinite("10"); // true

    isFinite(10); // true

    isFinite(undefined); // false

    isFinite(); // false

    isFinite(null); // true,這點當特別註意

30、避免在數組中使用負數做索引

    var numbersArray = [1,2,3,4,5];

     var from = numbersArray.indexOf("foo") ; // from is equal to -1

     numbersArray.splice(from,2); // will return [5]

  註意傳給splice的索引參數不要是負數,當是負數時,會從數組結尾處刪除元素。

31、用JSON來序列化與反序列化

    var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };

    var stringFromPerson = JSON.stringify(person);

    /* stringFromPerson 結果為 "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}" */

    var personFromString = JSON.parse(stringFromPerson);

    /* personFromString 的值與 person 對象相同 */

32、不要使用eval()或者函數構造器

    eval()和函數構造器(Function consturctor)的開銷較大,每次調用,JavaScript引擎都要將源代碼轉換為可執行的代碼。

    var func1 = new Function(functionCode);

    var func2 = eval(functionCode);

32、不要使用eval()或者函數構造器

    eval()和函數構造器(Function consturctor)的開銷較大,每次調用,JavaScript引擎都要將源代碼轉換為可執行的代碼。

    var func1 = new Function(functionCode);

    var func2 = eval(functionCode);

33、避免使用with()

    使用with()可以把變數加入到全局作用域中,因此,如果有其它的同名變數,一來容易混淆,二來值也會被覆蓋。

34、不要對數組使用for-in

  避免:

    var sum = 0;

    for (var i in arrayNumbers) {

      sum += arrayNumbers[i];

    }

  而是:

    var sum = 0;

    for (var i = 0, len = arrayNumbers.length; i < len; i++) {

      sum += arrayNumbers[i];

    }

    另外一個好處是,i和len兩個變數是在for迴圈的第一個聲明中,二者只會初始化一次,這要比下麵這種寫法快:

    for (var i = 0; i < arrayNumbers.length; i++)

35、傳給setInterval()和setTimeout()時使用函數而不是字元串

    如果傳給setTimeout()和setInterval()一個字元串,他們將會用類似於eval方式進行轉換,這肯定會要慢些,因此不要使用:

    setInterval('doSomethingPeriodically()', 1000);

    setTimeout('doSomethingAfterFiveSeconds()', 5000);

  而是用:

    setInterval(doSomethingPeriodically, 1000);

    setTimeout(doSomethingAfterFiveSeconds, 5000);

36、使用switch/case代替一大疊的if/else

  當判斷有超過兩個分支的時候使用switch/case要更快一些,而且也更優雅,更利於代碼的組織,當然,如果有超過10個分支,就不要使用switch/case了。

37、在switch/case中使用數字區間

  其實,switch/case中的case條件,還可以這樣寫:

    function getCategory(age) {

      var category = "";

      switch (true) {

        case isNaN(age):

        category = "not an age";

        break;

        case (age >= 50):

        category = "Old";

        break;

        case (age <= 20):

        category = "Baby";

        break;

        default:

        category = "Young";

        break;

        };

      return category;

  }

  getCategory(5); // 將返回 "Baby"

38、使用對象作為對象的原型

  下麵這樣,便可以給定對象作為參數,來創建以此為原型的新對象:

  function clone(object) {

      function OneShotConstructor(){};

      OneShotConstructor.prototype = object;

      return new OneShotConstructor();

  }

  clone(Array).prototype ; // []

39、HTML欄位轉換函數

  function escapeHTML(text) {

      var replacements= {"<": "<", ">": ">","&": "&", "\"": """};

      return text.replace(/[<>&"]/g, function(character) {

        return replacements[character];

      });

  }

40、不要在迴圈內部使用try-catch-finally

  try-catch-finally中catch部分在執行時會將異常賦給一個變數,這個變數會被構建成一個運行時作用域內的新的變數。

  切忌:

    var object = ['foo', 'bar'], i;

    for (i = 0, len = object.length; i <len; i++) {

      try {

      // do something that throws an exception

     }

     catch (e) {

    // handle exception

    }

  }

  而應該:

    var object = ['foo', 'bar'], i;

    try {

      for (i = 0, len = object.length; i <len; i++) {

      // do something that throws an exception

      }

    }

    catch (e) {

      // handle exception

    }

41、使用XMLHttpRequests時註意設置超時

  XMLHttpRequests在執行時,當長時間沒有響應(如出現網路問題等)時,應該中止掉連接,可以通過setTimeout()來完成這個工作:

  var xhr = new XMLHttpRequest ();

  xhr.onreadystatechange = function () {

    if (this.readyState == 4) {

    clearTimeout(timeout);

    // do something with response data

    }

  }

  var timeout = setTimeout( function () {

    xhr.abort(); // call error callback

  }, 60*1000 /* timeout after a minute */ );

  xhr.open('GET', url, true);

  xhr.send();

  同時需要註意的是,不要同時發起多個XMLHttpRequests請求。

42、處理WebSocket的超時

  通常情況下,WebSocket連接創建後,如果30秒內沒有任何活動,伺服器端會對連接進行超時處理,防火牆也可以對單位周期沒有活動的連接進行超時處理。

  為了防止這種情況的發生,可以每隔一定時間,往伺服器發送一條空的消息。可以通過下麵這兩個函數來實現這個需求,一個用於使連接保持活動狀態,另一個專門用於結束這個狀態。

    var timerID = 0;

    function keepAlive() {

      var timeout = 15000;

      if (webSocket.readyState == webSocket.OPEN) {

      webSocket.send('');

     }

      timerId = setTimeout(keepAlive, timeout);

    }

    function cancelKeepAlive() {

      if (timerId) {

        cancelTimeout(timerId);

      }

    }

  keepAlive()函數可以放在WebSocket連接的onOpen()方法的最後面,cancelKeepAlive()放在onClose()方法的最末尾。

43、時間註意原始操作符比函數調用快,使用VanillaJS

  比如,一般不要這樣:

    var min = Math.min(a,b);

    A.push(v);

  可以這樣來代替:

    var min = a < b ? a : b;

    A[A.length] = v;

44、開發時註意代碼結構,上線前檢查並壓縮JavaScript代碼

  別忘了在寫代碼時使用一個代碼美化工具。使用JSLint(一個語法檢查工具)並且在上線前壓縮代碼(比如使用JSMin)。註:現在代碼壓縮一般推薦 UglifyJS (https://github.com/mishoo/UglifyJS2)

45、JavaScript博大精深,這裡有些不錯的學習資源

     Code Academy資源:http://www.codecademy.com/tracks/javascript

     Marjin Haverbekex編寫的Eloquent JavaScript:http://eloquentjavascript.net/

     John Resig編寫的Advanced JavaScript:http://ejohn.org/apps/learn/

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 近年來,CSS不透明算得上是一種相當流行的技術,但在跨瀏覽器支持上,對於開發者來說,可以說是一件令人頭疼的事情。目前還沒有一個通用方法,以確保透明度設置可以在目前使用的所有瀏覽器上有效。 這篇彙總主要是提供一些CSS不透明的詳細介紹,代碼示例和解釋,以實現這項有用的CSS技術在您的項目中相容所有瀏覽 ...
  • [1]對象 [2]實例屬性 [3]構造函數屬性 [4]實例方法 ...
  • 使用EasyUi我們可以在客戶端表單提交之前進行驗證,過程如下:只需在onSubmit的時候使用return $("#form1").form('validate')方法即可,EasyUi中form模塊中的from('validate')方法會自行對我們指定的表單中required=true等需要驗 ...
  • 作者:vousiu 出處:http://www.cnblogs.com/vousiu 本實例參考自Mike Cantelon等人的《Node.js in Action》一書。 server.js 跟前文所說過的原因一樣,我認為此處的cache可以不作為參數傳進來。此處由於是傳引用因此不影響。但若傳的 ...
  • 作者:vousiu 出處:http://www.cnblogs.com/vousiu 本實例參考自Mike Cantelon等人的《Node.js in Action》一書。 index.html style.css ...
  • [1]定義 [2]特點 [3]元字元 [4]轉義字元 [5]字元組 [6]量詞 [7]括弧 [8]選擇 [9]斷言 [10]匹配模式 [11]優先順序 [12]局限性 ...
  • 作者:vousiu 出處:http://www.cnblogs.com/vousiu 本實例參考自Mike Cantelon等人的《Node.js in Action》一書。 這個程式在客戶端瀏覽器運行。負責對UI操作的響應和與chat_server的通信。 ...
  • 正則表達式的構造摘要 構造 匹配 字元 x 字元 x \\ 反斜線字元 \0n 帶有八進位值 0 的字元 n (0 <= n <= 7) \0nn 帶有八進位值 0 的字元 nn (0 <= n <= 7) \0mnn 帶有八進位值 0 的字元 mnn(0 <= m <= 3、0 <= n <= 7 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...