我的JS筆記 -- 模塊


模塊化可以使你的代碼低耦合,功能模塊直接不相互影響。

模仿塊級(jí)作用域

JS中沒有塊級(jí)作用域,而是函數(shù)作用域,函數(shù)中聲明的變量和函數(shù)不會(huì)泄露到外部作用域。那么就可以通過在函數(shù)中創(chuàng)建私有變量。

function f() {
    var a = 1;
}
a // ReferenceError: a is not defined

但是這樣函數(shù)名也是一個(gè)全局變量,也有污染全局變量的危險(xiǎn)。那么如果使用匿名函數(shù)呢?

// 這樣會(huì)報(bào)錯(cuò),函數(shù)聲明必須要有標(biāo)識(shí)符
function () {
    var a = 1; 
}

// 仍是會(huì)生成全局標(biāo)識(shí)符 
var f = function () {
    var a = 1;
}

JS中可以利用立即執(zhí)行函數(shù)模仿塊級(jí)作用域,立即函數(shù)是一個(gè)函數(shù)表達(dá)式而不是函數(shù)聲明,不會(huì)提升,解析到這行就會(huì)立即運(yùn)行。這樣既不會(huì)污染全局變量,函數(shù)也可以執(zhí)行。

// 寫法一
(function () {
    // 塊級(jí)作用域
}());

// 寫法二
(function () {
    // 塊級(jí)作用域
})();

// 寫法三
(function (fn) {
    fn();
})(function f() {
    // 塊級(jí)作用域
});

私有變量

JS中函數(shù)的參數(shù)、局部變量和函數(shù)內(nèi)部定義的函數(shù)都不能再函數(shù)的外部被訪問,所以被稱為私有變量。

那么有權(quán)訪問私有變量和私有函數(shù)的公有方法稱為特權(quán)方法。

特權(quán)方法是在對(duì)象上創(chuàng)建,一般有兩種方式:構(gòu)造函數(shù)定義特權(quán)方法和靜態(tài)私有變量實(shí)現(xiàn)特權(quán)方法。這兩種都是用于為自定義類型創(chuàng)建私有變量和特權(quán)方法的。

  • 構(gòu)造函數(shù)定義特權(quán)方法;

      function F() {
          var a = 1; // 私有變量
          function sayA() { // 私有函數(shù)
              console.log(a);
          }
          this.sayA = sayA; // 特權(quán)方法
      }
      var f = new F();
      f.sayA(); // 1
    

缺點(diǎn)是每個(gè)實(shí)例都會(huì)創(chuàng)建一組新方法,違反了構(gòu)造函數(shù)與實(shí)例對(duì)象相分離的原則。并且,非常耗費(fèi)內(nèi)存。

  • 靜態(tài)私有變量實(shí)現(xiàn)特權(quán)方法;

      (function () {
          var a = 1; // 私有變量
          function sayA()  { // 私有函數(shù)
              console.log(a);
          }
          // 構(gòu)造函數(shù)使用函數(shù)表達(dá)式,且不使用var,函數(shù)聲明只能創(chuàng)建局部變量,不使用var的函數(shù)表達(dá)式可以創(chuàng)建全局變量,讓其在私有作用域之外訪問
          F = function () {
              //
          };
          F.prototype.sayA = sayA; // 特權(quán)方法
      })();
      var f = new F();
      f.sayA(); // 1
    

缺點(diǎn)是私有變量是公用的,所有實(shí)例使用的都是相同的私有變量。

模塊模式

模塊模式是為單例創(chuàng)建私有變量和特權(quán)方法。

在JS可以利用立即執(zhí)行函數(shù)和閉包創(chuàng)建模塊。

模塊模式需要具備兩個(gè)必要條件:

  1. 必須有外部的封閉函數(shù), 該函數(shù)必須至少被調(diào)用一次( 每次調(diào)用都會(huì)創(chuàng)建一個(gè)新的模塊實(shí)例);

  2. 封閉函數(shù)必須返回至少一個(gè)內(nèi)部函數(shù), 這樣內(nèi)部函數(shù)才能在私有作用域中形成閉包, 并且可以訪問或者修改私有的狀態(tài);

    var f = function () {
    var a = 1; // 私有變量
    return { // 函數(shù)調(diào)用后返回一個(gè)包含公開屬性和方法的對(duì)象
    sayA: function () { // 特權(quán)方法,通過閉包可以在外部調(diào)用時(shí)訪問內(nèi)部私有變量
    console.log(a);
    }
    }
    };
    f().sayA(); // 1

利用匿名函數(shù)自執(zhí)行改寫

var f = (function () {
    var a = 1; // 私有變量
    return { // 函數(shù)調(diào)用后返回一個(gè)包含公開屬性和方法的對(duì)象
        sayA: function () {  // 特權(quán)方法,通過閉包可以在外部調(diào)用時(shí)訪問內(nèi)部私有變量
            console.log(a);
        }
    }
})();
f.sayA(); // 1

更多文章在 這里 ,覺得不錯(cuò)希望點(diǎn)個(gè) star

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容