js模式第五章

命名空間模式

命名空間有助於減小程序中所須要的全局變量的數量,而且同事還有助於避免命名衝突或過長的名字前綴。咱們能夠建立一個全局對象,將所需的方法,屬性添加到這個對象中。避免了變量全局污染。並且一樣能避免與第三庫的命名衝突。可是一樣存在一些缺點:dom

  • 使用的時候,須要附加全局對象這個前綴,增長了不少重複代碼。
  • 長嵌套名字意味着更長的屬性解析查詢時間
  • 一個全局對象意味着,任何部分的代碼都能修改這個全局對象,而且影響全部調用該對象的地方。

通用命名空間函數

當咱們往這個全局對象添加一個屬性時,可能覆蓋以前已經定義的屬性了,全部咱們在添加時,先得檢測這個添加的屬性在這個全局對象中是否已經存在。Code:模塊化

var MYAPP={};

if(typeof MYAPP === "undefined"){
    var MYAPP={};
}

var MYAPP = MYAPP || {};
複製代碼

這種檢測一個對象好使,可是檢測鏈式對象時,顯得乏力,代碼也會變得臃腫。全部咱們須要設計一個能夠檢測鏈式對象的方法。Code:函數

MYAPP.namespace('MYAPP.modules.module2');
複製代碼

具體的方法實現。Code:測試

var MYAPP = MYAPP || {};

MYAPP.namespace = function (ns_string){
    var parts = ns_string.split('.'),
        parent = MYAPP,
        i;
    if(parent[0] === "MYAPP"){
        parts = parts.slice(1);
    }

    for(i=0; i < parts.length; i++>){
        if(typeof parts[i] === "undefined"){
            parent[parts[i]]={};
        }
        parent = parent[parts[i]]
    }
    return parent;
};
複製代碼

聲明依賴關係

在函數或頂部聲明代碼所依賴的模塊是一個很好的方法。由於這種聲明僅涉及建立一個局部變量並使其指向所需的模塊。Code:this

var myFunction = function (){
    var event = YAHOO.util.Event,
        dom = YAHOO.util.Dom;
};
複製代碼

這種模式有以下幾個優勢:spa

  • 顯示的依賴聲明代表須要的特定腳本已經包含在該頁面中。
  • 在函數頂部的前期聲明可使頁面維護者很容易地發現並解析依賴。
  • 解析局部變量的速度老是要比解析全局變量(YAHOO)要快,甚至比使用全局變量的嵌套屬性(YAHOO.util.Dom)還要快。
  • 將第三方模塊賦值給重命名的局部變量,能夠擁有更好的代碼量,由於咱們可使用更短的局部變量。

私有屬性和方法

js中並無特殊的語法來表示私有、保護、或公共屬性和方法。由於js中全部對象的成員都是公共的。prototype

好比咱們隨便建立一個對象:設計

var obj{
    name:'nei',
    run:function(){
        console.log('Run');
    }
};

obj.name //公共的,能夠隨便訪問的。
複製代碼

即便使用構造函數一樣如此:code

function Obj(){
    this.name='Nei';
    this.run=function(){
        console.log('run');
    };
}

var o1=new Obj();

o1.name //公共的 能夠隨便訪問的
複製代碼

可是有時咱們須要私有成員,因此誕生了下面的這些生成私有成員的方法。對象

私有成員

雖然js自己沒有直接建立私有成員的方法,可是咱們將變量控制在函數做用域內,保證外部訪問不到它,這樣同樣能夠建立私有成員,好比咱們建立一個類,在類裏面建立一個局部變量,而後用公共方法將它暴露出去,這樣咱們就能夠建立一個私有變量,可是有個公共方法又能夠訪問到它。

function Nei(){
    var _name='nei';
    this.getName=function(){
        return _name;
    };
}

var n=new Nei();
n.name   //undefined
n.getName() //"nei"
複製代碼

模塊模式

模塊模式就以下幾種的集合:

  • 命名空間
  • 即時函數
  • 私有和特權成員
  • 聲明依賴

沙箱模式

顧名思義就是提供了一個可用於模塊運行的環境,且不會對其餘模塊和我的沙箱形成任何影響。

全局構造函數

命名空間模式中有一個全局對象,在沙箱模式中,咱們能夠設置一個全局構造函數,建立一個隔離的沙箱環境。Code:

new Sandbox(function(box)){
    ....
});
複製代碼

經過添加新特徵,使這個模式更先進:

  • 經過第三章的強制new模式,能夠假設在建立對象是不須要new操做符。
  • 構造函數能夠接受一個額外的配置參數(或多個),其中該參數指定了對象實例所須要的模塊名。但願代碼是模塊化的,所以絕大部分構造函數提供的功能將被限制在模塊中。

靜態成員

靜態成員分爲公有靜態成員和私有靜態成員

公有靜態成員

所謂公有就是直接暴露在對象的屬性上,外部能夠訪問。Code:

var Garget=function(){};

//靜態方法
Garget.isShiny=function(){
    return "you bet";
};

//普通方法
Garget.prototype.setPrice=function(price){
    this.price=price;
};

//能夠直接調用靜態方法
Garget.isShiny();//輸出 you bet

//普通方法必須建立一個實例,實例調用
var demo1=new Garget();
demo1.setPrice(12);
複製代碼

試圖以靜態方法調用一個實例方法是沒法正常運行的。一樣,若是使用實例調用靜態方法也是沒法正常運行的:

typeof Garget.setPrice; // undefined
typeof demo1.isShiny; // undefined
複製代碼

若是靜態方法也可以被實例調用,只需從新寫一個原型方法便可:

Garget.prototype.isShiny=Garget.isShiny;
demo1.isShiny; // 輸出 「you bet」
複製代碼

可是要注意這裏的this指向問題,執行Garget.isShiny時,this指向Garget。執行demo1.isShiny時,this指向demo1。

咱們能夠用instanceof肯定方法是如何被調用的:

var Garget=function(price){
     this.price=price
 };

 Garget.isShiny=function(){
     var msg="you bet";

     is(this instanceof Garget){
         msg += ", it costs $"+ this.price + "!";
     }
     return msg;
 };

 Garget.prototype.isShiny=function(){
     return Garget.isShiny.call(this);
 };

 //調用靜態方法
 Garget.isShiny; // 輸出 "you bet"

 //實例調用
 var d1=new Garget(12);
 d1.isShiny(); // 輸出 "you bet,it costs $12!"
複製代碼

私有靜態成員

私有靜態成員具備以下屬性:

  • 以同一個函數所建立的全部對象共享該成員
  • 構造函數外部不可訪問。

利用當即執行函數實現一個簡單的私有靜態成員:

var Garget=(function(){
    var counter=0;
    return function(){
        console.log(counter+=1);
    };
})();

//屢次調用
var d1=new Garget(); // 1
var d2=new Garget(); // 2
var d3=new Garget(); // 3
複製代碼

如今,咱們經過一個特權方法將私有屬性暴露出去:

var Garget=(function(){
    var counter=0,
        NewGarget;

    NewGarget=function(){
        counter+=1;
    };

    //私有特權方法
    NewGarget.prototype.getLastId=function(){
        return counter;
    };

    //重寫構造函數
    return NewGarget;
})();

//測試
var d1=new Garget();
d1.getLastId(); // 1
var d2=new Garget();
d2.getLastId(); // 2
var d3=new Garget();
d3.getLastId(); // 3
複製代碼

靜態屬性能夠包含非實例相關的方法和數據,而且不會爲每一個實例從新建立靜態屬性。

鏈模式

鏈模式最重要的一個要點,須要顯示返回的this對象。

相關文章
相關標籤/搜索