JavaScript - 設(shè)計(jì)模式 - 命名空間


本小節(jié)主要講解三種常用的設(shè)計(jì)模式和命名空間,第一種是工廠模式,第二種是單利模式,第三種是觀察者模式


設(shè)計(jì)模式概述

是為了解決在開(kāi)發(fā)中可能遇到的需求(相似),而提出的一套解決方法.

設(shè)計(jì)模式要求:

  • 在開(kāi)發(fā)中整個(gè)系統(tǒng)需要一套設(shè)計(jì)模式(架構(gòu)師)
  • 來(lái)源:建筑(建房子)領(lǐng)域
  • 設(shè)計(jì)模式的四人幫: Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides
  • 設(shè)計(jì)模式:總共有23種.
  • **設(shè)計(jì)模式類(lèi)型:?jiǎn)卫ɡ┠J健。^察者模式?。〈砟J健。S模式?。m配器模式 |橋接模式 | .... **
  • 設(shè)計(jì)模式的書(shū):<設(shè)計(jì)模式><大話設(shè)計(jì)模式|大話數(shù)據(jù)結(jié)構(gòu)><23種常見(jiàn)的設(shè)計(jì)模式>

工廠模式

批量創(chuàng)建大量的同類(lèi)型的對(duì)象

優(yōu)點(diǎn) :

  • 可以通過(guò)統(tǒng)一的借口來(lái)創(chuàng)建對(duì)象,根據(jù)傳入的參數(shù)不同來(lái)創(chuàng)建不同的對(duì)象,易于擴(kuò)展和維護(hù),穩(wěn)定性更好

核心過(guò)程 :

  • 提供一個(gè)父構(gòu)造函數(shù)
  • 設(shè)置這個(gè)父構(gòu)造函數(shù)的原型對(duì)象(屬性|方法)
  • 在父構(gòu)造函數(shù)身上添加靜態(tài)工廠方法

1.需要接收傳入的參數(shù)(要生產(chǎn)的產(chǎn)品的類(lèi)型)
2.判斷 是否支持生產(chǎn)
3.設(shè)置子構(gòu)造函數(shù)的原型對(duì)象
4.把新創(chuàng)建的對(duì)象返回

  • 定制合作伙伴

  • 直接使用父構(gòu)造函數(shù)的靜態(tài)工廠方法來(lái)創(chuàng)建指定的產(chǎn)品對(duì)象

  • 示例代碼 :

<script>
    //1. 提供一個(gè)父構(gòu)造函數(shù)
    function PhoneMake(){};
    //2. 設(shè)置這個(gè)父構(gòu)造函數(shù)的原型對(duì)象(屬性|方法)
    PhoneMake.prototype.logDes = function(){
        console.log("我們的口號(hào)是:" + this.des);
    }

    //3. 在父構(gòu)造函數(shù)身上添加靜態(tài)工廠方法
    PhoneMake.factory = function(typeStr){
        // 3.1 需要接收傳入的參數(shù)(要生產(chǎn)的產(chǎn)品的類(lèi)型)
        var productType =  typeStr;

        //var Dog = PhoneMake[productType];
        //3.2 判斷 是否支持生產(chǎn)
        if (typeof PhoneMake[productType]  != "function")
        {
            //拋出一個(gè)異常
            throw "對(duì)不起,我們工廠和這個(gè)品牌沒(méi)有商務(wù)合作,不能生產(chǎn)!"
        }

        //3.3 設(shè)置子構(gòu)造函數(shù)的原型對(duì)象
         //為了獲得構(gòu)造函數(shù)原型對(duì)象的方法
        PhoneMake[productType].prototype = new PhoneMake(); 

        //3.4 設(shè)置子構(gòu)造函數(shù)的原型對(duì)象
       var newProduct = new PhoneMake[productType]();

        //3.5 把新創(chuàng)建的對(duì)象返回
        return newProduct;
    }

    //4. 定制合作伙伴
    PhoneMake.iphone = function(){
        this.des = "最安全最穩(wěn)定的系統(tǒng),最垃圾的體驗(yàn)"
    }
    PhoneMake.oppo = function(){
        this.des = "充電兩小時(shí),通話五分鐘"
    }
    PhoneMake.vivo = function(){
        this.des = "照亮你的美,你本來(lái)就很美"
    }
    PhoneMake.meizu = function(){
        this.des = "我就是我,不一樣的魅族"
    }

    //5. 直接使用父構(gòu)造函數(shù)的靜態(tài)工廠方法來(lái)創(chuàng)建指定的產(chǎn)品對(duì)象
    var iphone = PhoneMake.factory("iphone");
    var vivo = PhoneMake.factory("vivo");
    var oppo = PhoneMake.factory("oppo");
    var meizu = PhoneMake.factory("meizu");
    var xiaomi = PhoneMake.factory("xiaomi");

    iphone.logDes();
    vivo.logDes();
    oppo.logDes();
    meizu.logDes();

</script>

單利模式

在整個(gè)程序的運(yùn)行過(guò)程中,一個(gè)類(lèi)只有一個(gè)實(shí)例對(duì)象

js中的單利模式

  • js沒(méi)有類(lèi)(ES6才有的) ,js實(shí)現(xiàn)單利模式(限定討論的范圍)

1.字面量
2.內(nèi)置構(gòu)造函數(shù)(Array Date Function Object)
3.工廠函數(shù)
4.自定義構(gòu)造函數(shù)(單利模式)

  • js是什么樣的語(yǔ)言

1.弱類(lèi)型,腳本,輕量級(jí),面向?qū)ο?基于原型(對(duì)象),解釋行語(yǔ)言.函數(shù)式.
2.js到底是不是一門(mén)面向?qū)ο?類(lèi))的語(yǔ)言?
3.js是一門(mén)支持面向?qū)ο蟮恼Z(yǔ)言.(封裝|繼承|多態(tài))

單利模式實(shí)現(xiàn)之后的表現(xiàn)

var p1 = new 構(gòu)造函數(shù)()
var p2 = new 構(gòu)造函數(shù)()
p1 == p2

  • 示例代碼 :
<script>
    function Person(){
        //首先創(chuàng)建一個(gè)空的對(duì)象
        //默認(rèn)把新的對(duì)象賦值給this
        //把新對(duì)象返回
    }
    var p1 = new Person();
    var p2 = new Person();
    console.log(p1 == p2);
</script>

單利模式的實(shí)現(xiàn)方式01 ----> 全局變量

全局變量來(lái)保存對(duì)象實(shí)現(xiàn)單利模式

  • 提供一個(gè)全局的變量
  • 提供一個(gè)構(gòu)造函數(shù)Person
  • 在構(gòu)造函數(shù)內(nèi)部先判斷全局變量是否有值,如果有那么就直接返回
  • 如果沒(méi)有,那么就把this賦值給全局變量
  • 通過(guò)this設(shè)置屬性和方法

存在的問(wèn)題

  • 使用一個(gè)全局變量來(lái)保存單利對(duì)象,該全局變量在整個(gè)作用域中都可以被訪問(wèn)或者是修改,可能會(huì)輕易的被覆蓋或者是修改.

  • 修改之后,創(chuàng)建出來(lái)的實(shí)例對(duì)象就不再是之前的那個(gè)單利對(duì)象了.

  • 示例代碼 :

<script>
    var instance;
    function Person(){
        if(instance)
        {
            console.log("對(duì)象已經(jīng)被創(chuàng)建,直接把之前創(chuàng)建好的對(duì)象返回");
            return instance;
        }
        instance = this;
        this.name = "奧特曼";
        this.age = 1000;
        console.log("第一次創(chuàng)建對(duì)象,創(chuàng)建對(duì)象之后并返回");
    }

    var p1 = new Person();
    var p2 = new Person();
    console.log(p1 == p2);
    var p3 = new Person();

    instance = "demo";
    var p4 = new Person();
    console.log(p4);
    console.log(p4 == p1);
</script>

單利模式的實(shí)現(xiàn)方式02 ----> 靜態(tài)屬性

靜態(tài)成員:直接添加到構(gòu)造函數(shù)身上的屬性或者是方法

存在的問(wèn)題

  • 構(gòu)造函數(shù)的靜態(tài)屬性其實(shí)也可能被修改,因此這種方法也不安全

  • 示例代碼 :

<script>
    function Person(){
        //判斷對(duì)象是否已經(jīng)被創(chuàng)建
        if (Person.instance)
        {
            console.log("之前已經(jīng)創(chuàng)建過(guò)對(duì)象,直接返回");
            return Person.instance;
        }

        this.name = "大黃蜂"
        Person.instance  = this;
        console.log("第一次創(chuàng)建");
    }

    var p1 = new Person();
    var p2 = new Person();
    console.log(p1 == p2);


    instance = "demo";
    var p3 = new Person();
    console.log(p1 == p3);

    Person.instance = "123";
    var p4 = new Person();
    console.log(p4 == p1);
</script>

單利模式的實(shí)現(xiàn)方式03 ----> 惰性函數(shù)

核心過(guò)程

  • 提供一個(gè)構(gòu)造函數(shù)

  • 在構(gòu)造函數(shù)內(nèi)部聲明一個(gè)私有的變量

  • 使用惰性函數(shù)定義更新構(gòu)造函數(shù)的實(shí)現(xiàn)(直接把instance返回)

  • 設(shè)置原型對(duì)象[新構(gòu)造函數(shù)的原型對(duì)象 = 舊構(gòu)造函數(shù)的原型對(duì)象]
    構(gòu)造函數(shù),prototype == 對(duì)象.proto

  • 使用新的構(gòu)造函數(shù)創(chuàng)建實(shí)例對(duì)象,并且賦值給instance

  • 修正對(duì)象的構(gòu)造函數(shù)指向

  • 通過(guò)instance設(shè)置實(shí)例屬性和方法

  • 示例代碼 :

<script>
    // 01 提供一個(gè)構(gòu)造函數(shù)
    function Person(){
        //this01
        //02 在構(gòu)造函數(shù)內(nèi)部聲明一個(gè)私有的變量
        var instance;
        //03 使用惰性函數(shù)定義更新構(gòu)造函數(shù)的實(shí)現(xiàn)(直接把instance返回)
        Person = function(){
            //內(nèi)部默認(rèn)會(huì)創(chuàng)建一個(gè)空的對(duì)象 this02
            return instance;
        }
        //04 設(shè)置原型對(duì)象[新構(gòu)造函數(shù)的原型對(duì)象 = 舊構(gòu)造函數(shù)的原型對(duì)象]
        //原型鏈繼承:Man.prototype = new Person();
        //原型式繼承:Man.prototype = Person.prototype;
        //Person.prototype = this.__proto__;  //非標(biāo)準(zhǔn)(代碼中不要出現(xiàn))
        Person.prototype = this;

        //05 使用新的構(gòu)造函數(shù)創(chuàng)建實(shí)例對(duì)象,并且賦值給instance
        instance = new Person();
        //instance = this;
        //06 修正對(duì)象的構(gòu)造函數(shù)指向
        instance.constructor = Person;
        // 07 通過(guò)instance設(shè)置實(shí)例屬性和方法
        instance.name = "我很好聽(tīng)";
        // 08 把instance返回
        return instance;
    }

    Person.prototype.des = "描述信息";
    var p1 = new Person();
    Person.prototype.hi = "hi";

    var p2 = new Person();
    console.log(p1 == p2);

    console.log(p1.constructor == Person);  //true
    console.log(p1.des);
    console.log(p1.hi);
</script>

單利模式的實(shí)現(xiàn)方式04 ----> 全局變量 + 即時(shí)函數(shù)

  • 示例代碼 :
<script>
    var Person;
    (function(){
        var instance;

        Person = function (){
            if(instance)
            {
                return instance;
            }
            this.name = "momo";
            instance = this;
        }
    })();

    var p1 = new Person();
    var p2 = new Person();
    console.log(p1 == p2);
</script>

觀察者模式

觀察者模式舉例說(shuō)明

  • 男生A和男生B同時(shí)都喜歡女生C,他們想時(shí)時(shí)監(jiān)視女生C的動(dòng)向,動(dòng)態(tài),所以他們找了女生C的閨蜜作為觀察者幫他們監(jiān)視實(shí)時(shí)動(dòng)態(tài).這樣不管女生C有什么最新的動(dòng)態(tài)都會(huì)被男生A和男生B監(jiān)聽(tīng)到,開(kāi)發(fā)中就是男生多了點(diǎn),動(dòng)態(tài)多了點(diǎn),核心內(nèi)容就是這樣

  • 要求:

女神:rose(發(fā)布者)
男生:jack(訂閱者)
男生:tom(訂閱者)

  • 過(guò)程:

創(chuàng)建或者是設(shè)置一個(gè)發(fā)布者
創(chuàng)建訂閱者對(duì)象
注冊(cè)訂閱者
測(cè)試(發(fā)狀態(tài))

  • 示例代碼1 : 一個(gè)發(fā)布者,兩個(gè)訂閱者,關(guān)注的是一個(gè)狀態(tài)
<script>
    //01 創(chuàng)建或者是設(shè)置一個(gè)發(fā)布者
    var rose = {
        user:[],
        addUser:function(fn){
            if (typeof fn != "function")
            {
                throw "不支持該操作!";
            }
            this.user.push(fn);
        },
        removeUser:function(fn){
            for (var i = 0; i < this.user.length; i++) {
                if(this.user[i] == fn)
                {
                    console.log(fn + "取消了訂閱");
                    this.user.splice(i,1);
                }
            }
        },
        eat:function(){
            for (var i = 0; i < this.user.length; i++) {
               this.user[i]();
            }
        }
    }


    // 02 創(chuàng)建訂閱者對(duì)象
    var jack = {
        eat_jack:function(){
            console.log("我陪你去吃拉面吧  ---jack");
        }
    }
    var tom = {
        eat_tom:function(){
            console.log("我陪你去吃壽司吧  ---tom");
        }
    }

    // 03 注冊(cè)訂閱者
    rose.addUser(jack.eat_jack);
    rose.addUser(tom.eat_tom);

    //04 發(fā)布者狀態(tài)改變
    rose.eat();
    rose.removeUser(jack.eat_jack);
    rose.eat();
</script>
  • 示例代碼2 : 多個(gè)狀態(tài)
<script>
    //01 創(chuàng)建或者是設(shè)置一個(gè)發(fā)布者
    var publisher = {
        addUser:function(fn,type){
            var type = type || "eat";
            if (typeof fn != "function")
            {
                throw "不支持該操作!";
            }
            this.user[type].push(fn);
        },
        removeUser:function(fn,type){
            var type = type || "eat";
            for (var i = 0; i < this.user[type].length; i++) {
                if(this.user[type][i] == fn)
                {
                    console.log(fn + "取消了訂閱");
                    this.user[type].splice(i,1);
                }
            }
        },
        eat:function(){
            for (var i = 0; i < this.user["eat"].length; i++) {
               this.user["eat"][i]();
            }
        },
        sleep:function(){
            for (var i = 0; i < this.user["sleep"].length; i++) {
                //console.log(this.user,"++++");
                this.user["sleep"][i]();
            }
        }
    }

    var rose = {};
    //封裝一個(gè)函數(shù)用來(lái)快速的讓某個(gè)指定對(duì)象成為發(fā)布者
    function makePublisher(o){
        for(var i in publisher)
        {
            if (publisher.hasOwnProperty(i) && typeof publisher[i] == "function" ){
                o[i] = publisher[i];
            }
        }
        o.user = {
            eat:[],
            sleep:[]
        };
    }
    makePublisher(rose);

    // 02 創(chuàng)建訂閱者對(duì)象
    var jack = {
        eat_jack:function(){
            console.log("我陪你去吃拉面吧  ---jack");
        },
        sleep_jack:function(){
            console.log("晚安 rose  ---jack");
        }
    }

    // 03 注冊(cè)訂閱者
    rose.addUser(jack.eat_jack,"eat");        //關(guān)注rose肚子餓不餓
    rose.addUser(jack.sleep_jack,"sleep");     //關(guān)注rose困不困

    rose.eat();
    rose.sleep();
  • 示例代碼3 : 通用性處理
<script>
    //01 創(chuàng)建或者是設(shè)置一個(gè)發(fā)布者
    var publisher = {
        addUser:function(fn,type){
            var type = type || "eat";
            if (this.user[type] == undefined)
            {
                this.user[type] = [];
            }
            if (typeof fn != "function")
            {
                throw "不支持該操作!";
            }
            this.user[type].push(fn);
        },
        removeUser:function(fn,type){
            this.publish(type,fn);
        },
        publish:function(type,fn){
            var type = type || "eat";
            for (var i = 0; i < this.user[type].length; i++) {
                //判斷當(dāng)前是要取消訂閱還是要發(fā)布狀態(tài)
                if (typeof fn == "function")
                {
                    if(this.user[type][i] == fn)
                    {
                        console.log(fn + "取消了訂閱");
                        this.user[type].splice(i,1);
                    }
                }else
                {
                    this.user[type][i]();
                }

            }
        }
    }
    var rose = {
        eat:function(){
            this.publish("eat");
        },
        sleep:function(){
            this.publish("sleep");
        },
        read:function(){
            this.publish("read");
        }
    };
    function makePublisher(o){
        for(var i in publisher)
        {
            if (publisher.hasOwnProperty(i) && typeof publisher[i] == "function" ){
                o[i] = publisher[i];
            }
        }
        o.user = {
            eat:[],
            sleep:[]
        };
    }
    makePublisher(rose);

    var jack = {
        eat_jack:function(){
            console.log("我陪你去吃拉面吧  ---jack");
        },
        sleep_jack:function(){
            console.log("晚安 rose  ---jack");
        }
    }
    var tom = {
        eat_tom:function(){
            console.log("我買(mǎi)給你吧  ---tom");
        },
        sleep_tom:function(){
            console.log("今晚的太陽(yáng)很好看 ---tom");
        },
        read_tom:function(){
            console.log("你也在學(xué)習(xí)js嗎?");
        }
    }

    rose.addUser(jack.eat_jack,"eat");
    rose.addUser(tom.sleep_tom,"sleep");
    rose.addUser(tom.read_tom,"read");
    rose.eat();
    rose.sleep();
    rose.read();

</script>
  • 示例代碼4 : 訂閱者成為發(fā)布者
<script>
    //01 創(chuàng)建或者是設(shè)置一個(gè)發(fā)布者
    var publisher = {
        addUser:function(fn,type){
            var type = type || "eat";
            if (this.user[type] == undefined)
            {
                this.user[type] = [];
            }
            if (typeof fn != "function")
            {
                throw "不支持該操作!";
            }
            this.user[type].push(fn);
        },
        removeUser:function(fn,type){
            this.publish(type,fn);
        },
        publish:function(type,fn){
            var type = type || "eat";
            for (var i = 0; i < this.user[type].length; i++) {
                //判斷當(dāng)前是要取消訂閱還是要發(fā)布狀態(tài)
                if (typeof fn == "function")
                {
                    if(this.user[type][i] == fn)
                    {
                        console.log(fn + "取消了訂閱");
                        this.user[type].splice(i,1);
                    }
                }else
                {
                    this.user[type][i]();
                }

            }
        }
    }
    var rose = {
        eat:function(){
            this.publish("eat");
        },
        sleep:function(){
            this.publish("sleep");
        },
        read:function(){
            this.publish("read");
        },
        lol_rose:function(){
            console.log("你怎么又在打游戲?還是游戲比較重要一些?")
        }
    };
    function makePublisher(o){
        for(var i in publisher)
        {
            if (publisher.hasOwnProperty(i) && typeof publisher[i] == "function" ){
                o[i] = publisher[i];
            }
        }
        o.user = {
            eat:[],
            sleep:[]
        };
    }
    makePublisher(rose);

    var jack = {
        eat_jack:function(){
            console.log("我陪你去吃拉面吧  ---jack");
        },
        sleep_jack:function(){
            console.log("晚安 rose  ---jack");
        },
        statusLol:function(){
            this.publish("lol");
        }
    }
    var tom = {
        eat_tom:function(){
            console.log("我買(mǎi)給你吧  ---tom");
        },
        sleep_tom:function(){
            console.log("今晚的太陽(yáng)很好看 ---tom");
        },
        read_tom:function(){
            console.log("你也在學(xué)習(xí)js嗎?");
        },
        lol_rose:function(){
            console.log("好兄弟,終于來(lái)啦");
        }
    }

    rose.addUser(jack.eat_jack,"eat");

    rose.addUser(tom.sleep_tom,"sleep");
    rose.addUser(tom.read_tom,"read");
    rose.eat();
    rose.sleep();
    rose.read();

    //設(shè)置jack成為發(fā)布者,狀態(tài)(lol)
    makePublisher(jack);
    jack.addUser(rose.lol_rose,"lol");
    jack.addUser(tom.lol_rose,"lol");
    jack.statusLol();

</script>

備忘模式(函數(shù)結(jié)構(gòu)緩存)

特定場(chǎng)合:

  • 計(jì)算的函數(shù)f()
  • 某些參數(shù)需要進(jìn)行大規(guī)模反復(fù)的計(jì)算,可以考慮吧計(jì)算的結(jié)果保存起來(lái)
    f(n) ..... =>1000m
    代碼中某些參數(shù)可能會(huì)反復(fù)計(jì)算
    f(10) ===>ssddd
    f(10) ===>ssddd

使用一個(gè)緩存對(duì)象cacheObj{key-value}

  • 思路:

1.提供一個(gè)全局的對(duì)象(緩存對(duì)象),key-value
2.當(dāng)我們傳遞參數(shù)需要進(jìn)行計(jì)算(邏輯)的時(shí)候,先檢查緩存對(duì)象中是否有對(duì)應(yīng)的結(jié)果
3.如果有緩存數(shù)據(jù),那么就直接使用(可以節(jié)省時(shí)間,提高效率)
4.如果沒(méi)有緩存數(shù)據(jù),那么這個(gè)時(shí)候再執(zhí)行計(jì)算操作,處理得到結(jié)果之后,把這個(gè)數(shù)據(jù)保存起來(lái)
5.函數(shù)的參數(shù)作為緩存對(duì)象的key,把函數(shù)計(jì)算的結(jié)果作為這個(gè)key對(duì)應(yīng)的值

  • 示例代碼 :
<script>
    var cache = {};
    function f1(str){
        //.....
        if (cache[str] != undefined)
        {
            console.log("已經(jīng)存在緩存數(shù)據(jù),直接返回");
            return cache[str];
        }
        //....如果緩存中有數(shù)據(jù),那么函數(shù)體后面的代碼就不再執(zhí)行(節(jié)省時(shí)間)

        //執(zhí)行耗時(shí)操作...
        var result = str + " hello world!";
        cache[str] = result;
        console.log("第一次調(diào)用函數(shù)傳入?yún)?shù),返回結(jié)果");
        return result;
    }

    console.log(f1("demo"));   //
    console.log(f1("demo"));   //
    console.log(f1("demo"));
</script>
<script>
    function f1(str){
        //.....
        if (f1.cache[str] != undefined)
        {
            console.log("已經(jīng)存在緩存數(shù)據(jù),直接返回");
            return f1.cache[str];
        }
        //....如果緩存中有數(shù)據(jù),那么函數(shù)體后面的代碼就不再執(zhí)行(節(jié)省時(shí)間)

        //執(zhí)行耗時(shí)操作...
        var result = str + " hello world!";
        f1.cache[str] = result;
        console.log("第一次調(diào)用函數(shù)傳入?yún)?shù),返回結(jié)果");
        return result;
    }

    f1.cache = {};
    console.log(f1("test"));  //
    console.log(f1("test"));   //
    console.log(f1("test"));
</script>

命名空間模式:

寫(xiě)法:就是把所有的東西都寫(xiě)在一個(gè)對(duì)象里面.

命名:命名空間的名稱一般是項(xiàng)目的名稱或者是簡(jiǎn)寫(xiě),要求所有的字符都大寫(xiě)

  • 示例代碼 :
<script>
    //01 普通的變量
    var a = "a";
    var b = "b";

    //02 對(duì)象
    var obj = {
        name:"xxx"
    }

    function func (){
        console.log("func");
    }

    function Person(){
        this.name = "默認(rèn)的名稱";
    }
    function func (){
        console.log("func");
    }
</script>
<script>
    var MOMO = {};
    //01 普通的變量
    MOMO.a = "a";
    MOMO.b = "b";

    //02 對(duì)象
    MOMO.obj = {
        name:"zahngsan"
    }

    MOMO.func = function(){
        console.log("func");
    }

    MOMO.Person = function(){
        this.name = "默認(rèn)的名稱";
    }

    console.log(new  MOMO.Person());
</script>
<script>
//    var MOMO ={};
//    MOMO.obj = {
//        name:"張三"
//    };
//
//    MOMO.obj = "demodede";

    //在使用或者是對(duì)屬性進(jìn)行賦值之前,會(huì)先做一個(gè)檢查(檢查改屬性或者是方法是否存在)
    //var MOMO = {};  不推薦

    //02 更安全的處理方式:麻煩
//    if (MOMO == undefined)
//    {
//        var MOMO = {};
//    }

    var MOMO = MOMO || {};      //邏輯或 如果MOMO為真那么返回MOMO,否則就返回{}
    //if (MOMO.name == undefined)
    if ( typeof MOMO.name == 'undefined')
{
    MOMO.name = "測(cè)試的名稱";
}

    if ( typeof MOMO.age == 'undefined')
    {
        MOMO.age = 20;
    }

    //100屬性

</script>

通用的命名空間函數(shù)

在命名空間上面提供一個(gè)方法(nameSpace)

  • 得到調(diào)用函數(shù)傳入的字符串
  • 把字符串轉(zhuǎn)換為字符串?dāng)?shù)組
  • 把MOMO最外層去掉(刪除)
  • 遍歷
  • 示例代碼 :
<script>
    var MOMO = MOMO || {};
    MOMO.namespace = function(stringParam){
        var str = stringParam;
        var parts = str.split(".");   //根據(jù)字符串切割字符串變成一個(gè)數(shù)組
        var parent = MOMO;

        console.log(parts);

        if(parts[0] == "MOMO")
        {
            parts = parts.slice(1)    //作用:刪除第一個(gè)元素返回一個(gè)新的數(shù)組
        }

        for (var i = 0; i < parts.length; i++) {
            //MOMO.name
            //name.des
            //des.abc
            if (parent[parts[i]] == undefined)
            {
                parent[parts[i]] = {};
            }
            //更新父節(jié)點(diǎn)
            parent = parent[parts[i]];
        }
    }

    MOMO.namespace("MOMO.name.des.abc");
    console.log(MOMO);

    MOMO.namespace("MOMO.a.b.c.d.e.f.d.g.h.j.k.s.d.g.h.j.a.s.d.f.we.r");
    console.log(MOMO);
    MOMO.namespace("abc.des.abc");
    console.log(MOMO);
</script>

截至今日,面向?qū)ο蠛蚃avaScript進(jìn)階內(nèi)容已經(jīng)全部更新完畢! 內(nèi)容是比較詳細(xì)的,只要跟著每一篇的博文仔細(xì)學(xué)習(xí),比你看網(wǎng)上的垃圾視頻強(qiáng)多了 ! 理論和實(shí)踐相結(jié)合 更多的是得動(dòng)手去敲,以后還請(qǐng)大家多多關(guān)注更新,日后定會(huì)上一些新穎的東西和大家見(jiàn)面 !


最后編輯于
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 老劉最近把朋友圈關(guān)了。 我打電話給他約他出來(lái)吃飯,問(wèn)他:“你這么一個(gè)不安分的人,怎么突然一下子把朋友圈關(guān)了?” 老...
    大貓卡門(mén)閱讀 521評(píng)論 0 0
  • 參加于斯的文化培訓(xùn)課聽(tīng)了韓冰老師的599,方百里老師的指法練習(xí)教材,還有宋涵老師的小湯等教材,受益很多,每位老師都...
    胡美美閱讀 892評(píng)論 0 3
  • 不知從何時(shí)開(kāi)始,“宮寒”一詞闖入女人們的生活。 不管是小到月經(jīng)不調(diào)、痛經(jīng),還是大到不孕不育,除了癌癥,幾乎所有婦科...
    沐晨雨rara閱讀 1,443評(píng)論 0 0
  • 今天上班第一天,我就長(zhǎng)了個(gè)記性,媽呀我的小電驢居然追尾人家,傷心π_π,我還重重摔了一跤,摔在地上的時(shí)候我還起不來(lái)...
    言如心閱讀 235評(píng)論 0 0

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