(譯文)12個簡單(但強大)的JavaScript技巧(二)


原文鏈接: 12 Simple (Yet Powerful) JavaScript Tips

其他鏈接: (譯文)12個簡單(但強大)的JavaScript技巧(一)

強大的立即調用函數表達式

(什么是立即調用函數表達式, 何時使用它)

IIFE (Immediately Invoked Function Expressions, 發音:“Iffy”)是立即調用函數表達式的縮寫形式, 它的語法大概如下:

(function() {
  //Do fun stuff
})() 

這是一個立即調用的匿名函數, 它在JavaScript中有一些特別重要的作用.

它是如何工作的?
  • 包圍匿名函數的一對括號會把它變成函數表達式或者變量表達式.

  • 這就相當於:

    //不帶括號:
    ? = function() {};
    	
    //帶括號:
    (? = function() {});
    //函數被一個不知名的變量引用了, 一對括號把它包圍了, 把它變成了一個匿名的函數表達式
    

    同樣的, 我們甚至可以創建一個命名的立即調用函數表達式:

    (showName = function(name) {
      console.log( name || "No Name");
    })();	//No Name
    
    showName("Rich");	//Rich
    showName();		//NoName
    
  • 記住, 當你不用var關鍵詞創建變量的時候, JavaScript會自動判斷該變量為全局變量. 在上面的例子中是沒有必要使用var關鍵詞的(因為你之后可能會調用它).

  • 我們可以馬上或者在這之后使用這個函數

  • 但是我們不可以在之后調用匿名函數. 因為除非你創建匿名函數之后馬上調用, 在這之后沒有其他辦法可以引用它. 這是匿名函數只可以馬上調用它的原因.


  • 當把匿名函數包含在一對括號里面時(字面量), 整個字面量會被運算,並且返回匿名函數的返回值. 它的返回值實質上是整個匿名函數自身, 所以我們只需要在這之后加上一對括號來馬上調用它.

  • 因此, 后面的一對括號等於告訴JavaScript編譯器馬上調用這個匿名函數, 所以它才會被稱之為"立即調用函數表達式".

  • 因為JavaScript基於函數塊的作用域規則, 在匿名函數內聲明變量都是局部變量, 所以這些局部變量沒辦法直接從外部獲取.

  • 就像其他函數一樣, 你可以向匿名函數設定參數和傳遞變量. 你可以根據這個特性, 利用匿名函數的作用域擴展它外圍函數的作用域(即閉包).

什么時候應該使用它?

  1. 避免污染全局作用域

    IIFE最廣泛的用途是避免污染全局作用域. 已經有很多JavaScript庫和JavaScript高手正在使用這種技巧, 尤其是在最流行jQuery插件的開發者中. 你也應該把這個技巧應用在你的程序的主要文件中(main.js).

    在這個例子中, 我使用了匿名函數把所有全局作用域的變量變成了局部變量, 所以現在全局作用域中還可以定義新的變量, 不用顧忌是否會和匿名函數內的變量在變量名上發生沖突(還包括其他庫或者框架):

    //所有的代碼包含在立即調用函數中
    (function() {
      var firstName = "Richard";
      funtion init() {
    	doStuff(firstName);
    	//在這里開始插入應用程序的代碼...
      }
      
      function doStuff() {
        //...
      }
      
      function doMoreStuff() {
        //...
      }
      
      //啟動應用程序;
      init();
    })();
    
  2. 用作條件選擇器

    這種使用方式還沒有被廣泛所知, 但它是相當強大的. 你可以不調用一個命名函數來處理復雜的運算的. 注意在三目運算符(.. ? .. : .. )中的兩個匿名函數, 我盡可能多地加入空白來使語句看起來更容易理解:

    var unnamedDocs = [],
        namedDocs = ['a_bridge_runover', 'great_dreamers'];
    
    function createDoc(documentTitle) {
      var documentName = documentTitle
      
      ?
      
      (function(theName) {
        var newNamedDoc = theName.toLocaleLowerCase().replace('', '_');
        nameDocs.push(newNamedDoc);
        
        return newNamedDoc;
      })(documentTitle)
      
      :
      
      (function() {
        var newUnnamedDoc = 'untitled_' + Number(namedDocs.length + 1);
        unnamedDocs.push(newUnnamedDoc);
        return newUnnamedDoc;
      })();
      
      return documentName;
    }
    
    createDoc('Over The Rainbow'); //over_the rainbow
    createDoc(); //untitled_4
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM