常見設(shè)計(jì)模式

常見設(shè)計(jì)模式

構(gòu)造函數(shù)模式剃幌、混合模式、模塊模式税肪、工廠模式溉躲、單例模式、發(fā)布訂閱模式的范例益兄。
  • 工廠模式 factory
// 抽象了創(chuàng)建具體對(duì)象的過程
function createPerson(name){
  var person = {
    name : name
  };
  person.sayName : function(){
    console.log(this.name)  // this指向調(diào)用的方法
  }
  return person
}
createPerson("yym")  // 創(chuàng)建一個(gè)新的引用
createPerson("yangyu")

// 工廠模式

function createPerson(name, age, job){
  var o = new Object()
  o.name = name
  o.age = age
  o.job = job
  o.sayName = function(){
    console.log(this.name)
  } 
  return o
}

var person1 = createPerson("yym", 15, "work")
var person2 = createPerson("yym三國(guó)殺", 15, "wo是rk")
console.log(person1)

// 根據(jù)接受的參數(shù)構(gòu)建一個(gè)包含所有必要信息的對(duì)象,無數(shù)次調(diào)用這個(gè)函數(shù)
  • 構(gòu)造函數(shù)模式 constructor

與工廠模式的區(qū)別

  • 沒有顯式的創(chuàng)建對(duì)象
  • 直接將屬性和方法賦給了this對(duì)象
  • 沒有return語(yǔ)句

new操作符經(jīng)歷的步驟

  1. 創(chuàng)建一個(gè)新對(duì)象
  2. 將構(gòu)造函數(shù)的作用域賦給新對(duì)象(this只想這個(gè)新對(duì)象)
  3. 執(zhí)行構(gòu)造函數(shù)中的代碼
  4. 返回新對(duì)象
function Person(name, age){  //創(chuàng)建對(duì)象
  this.name = name
  this.age = age
  this.sayname = function(){    // 問題: 每個(gè)方法在實(shí)例時(shí)都要重新一遍
    return this.name
  }
// this.sayName = new Function("alert(this.name)")
}

var student = new Person('yym',  24)  // new 一個(gè)新對(duì)象
console.log(students)

alert(student.constructor === Person)  // true
alert(student instanceof Object)  // true
  • 原型模式
    無論何時(shí),只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),會(huì)根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性,屬性指向函數(shù)的原型對(duì)象,默認(rèn)情況下,所有原型對(duì)象會(huì)自動(dòng)獲得一個(gè)constructor(構(gòu)造函數(shù))屬性,是一個(gè)指向prototype屬性所在函數(shù)的指針
function Person(){
}
Person.prototype.name = "yym"
Person.prototype.age = 24
Person.prototype.job = "work"
Person.prototype.sayName = function(){
  console.log(this.name)
}

var person1 = new Person()
console.log(person1.sayName())
var person2 = new Person()
console.log(person2.sayName())
console.log(person1.sayName == person2.sayName)  // true

//isPrototypeOf() 確定是否__proto__指向調(diào)用對(duì)象(Person.prototype)
alert(Person.prototype.isPrototypeOf(person1))  // true

// ES5新方法: Object.getPrototypeOf()
alert(Object.getPrototypeOf(person1) == Person.prototype)  // true

// hasOwnProperty() 檢查一個(gè)屬性是存在于實(shí)例中,還是原型中
alert(person1.hasOwnProperty("name"))  // false

// in操作符會(huì)在通過對(duì)象能夠訪問給定屬性時(shí)返回true,無論實(shí)例
// 還是原型中
console.log("name" in person1)  // true
person1.name = "yangyu"
console.log("name" in person1)  // true

//使用for-in循環(huán),返回的所有能夠通過對(duì)象訪問的,可枚舉的屬性
//既包括實(shí)例中的屬性,也包括原型中的屬性

// 要取得對(duì)象上所有的可枚舉實(shí)例屬性,可用ES5中的 Object.keys()
// 接受一個(gè)對(duì)象作為參數(shù),返回一個(gè)字符串?dāng)?shù)組
var a = Object.keys(Person.prototype)
console.log(a) // ["name", "age", "job", "sayName"]

//想要得到所有實(shí)例屬性,無論是否可枚舉. Object.getOwnPropertyNames()
var key = Object.getOwnPropertyNames(Person.prototype)
console.log(key)  //["constructor", "name", "age", "job", "sayName"]
  • 混合模式 mixin
// 混合它的原型
//Person 構(gòu)造函數(shù)
var Person = function(name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.sayName = function(){
  console.log(this.name)
}
// Student 構(gòu)造函數(shù)
var Student = function(name, age, score){
  Person.call(this, name, age)  // 繼承
  this.score = score
}
// 原型式繼承
// Student.prototype = Object.create(Person.prototype)
Student.prototype = create(Person.prototype)

function create(parentObj){
  function F(){}  // 空對(duì)象 構(gòu)造函數(shù)
  F.prototype = parentObj  // 原型鏈上是傳進(jìn)來的對(duì)象
  return new F()  //  實(shí)例化構(gòu)造函數(shù)
}

Student.prototype.sayScore = function(){
  console.log(this.score);
}

var student = new Student("yym", 22, 100)
console.log(student)

// 原型式繼承
// 函數(shù)內(nèi)部創(chuàng)造一個(gè)臨時(shí)構(gòu)造函數(shù),傳入對(duì)象作為構(gòu)造函數(shù)原型,返回實(shí)例
function object(o){
  function F(){}
  F.prototype = o
  return new F()
}
  • 單例模式 singleton
// 匿名函數(shù)
var People = (function(){  // 閉包
  var instance;
  function init(name){
    return {
      name: name
    };
  };
  return {
    createPeople : function(name){
      if(!instance){
        instance = init(name)
      }
      return instance;
    }
  };
}())
console.log(People.createPeople("yym"))  // { name: "yym"}
console.log(People.createPeople("hello"))  // { name: "yym"}
  • 模塊模式 module
// 通過閉包實(shí)現(xiàn)一個(gè)模塊
var Person = (function(){
  var name = "yym"
  function sayName(){
    console.log(name)
  };  // 詞法作用域
  return {
    name: name,
    sayName: sayName
  }
}())
  • 發(fā)布訂閱模式 publish / subscibe
var EventCenter = (function(){
  var events = {};  // 存儲(chǔ)所有的key/value  事件映射表
  // 事件 回調(diào)函數(shù)
  // 1. on做了什么  ('hello',function(){})
  function on(evt,handler){
    // events['hello'] = []
    events[evt] = events[evt] || [];
    /* events['hello'] = [{
         handler: handler
       }]
    */
    events[evt].push({
      handler: handler
    });
  }
  //事件 所有的參數(shù)
  // 2. fire怎么做 ('hello')
  function fire(evt,args){
    // hello 有的 不執(zhí)行
    if(!events[evt]){
      return;
    }
    // 觸發(fā) handler
    for(var i=0; i<events[evt].length; i++){
      events[evt][i].handler(args);
    }
  }
  function off(evt){
    delete events[evt]
  }
  return {
    on: on,
    fire: fire,
    off : off  // 取消訂閱
  }
})()

EventCenter.on('hello', function(data){
  console.log('Hello World');
});
EventCenter.fire('hello');
使用發(fā)布訂閱模式寫一個(gè)事件管理器锻梳,可以實(shí)現(xiàn)如下方式調(diào)用
Event.on('change', function(val){
 console.log('change...  now val is ' + val);  
});
Event.fire('change', '饑人谷');
Event.off('changer');
var Event = (function (){
        var events = {};

        function on(evt, handle){
            events[evt] = events[evt] || [];
            events[evt].push({
                handle:handle
            });
        };

        function fire(evt,args){
            if(!events[evt]){
                return
            }

            for(var i=0; i<events[evt].length; i++){
                events[evt][i].handle(args);
            }
        };

        function off(evt){
            delete events[evt]
        };

        return {
            on: on,
            fire: fire,
            off: off
        }

    })()

    Event.on('change', function(val){
        console.log('change…… now val is' + val);
    });
    Event.fire('change', '饑人谷');
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市净捅,隨后出現(xiàn)的幾起案子疑枯,更是在濱河造成了極大的恐慌,老刑警劉巖蛔六,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荆永,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡国章,警方通過查閱死者的電腦和手機(jī)具钥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來液兽,“玉大人骂删,你說我怎么就攤上這事。” “怎么了桃漾?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵坏匪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我撬统,道長(zhǎng)适滓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任恋追,我火速辦了婚禮凭迹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苦囱。我一直安慰自己嗅绸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布撕彤。 她就那樣靜靜地躺著鱼鸠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪羹铅。 梳的紋絲不亂的頭發(fā)上蚀狰,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音职员,去河邊找鬼麻蹋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛焊切,可吹牛的內(nèi)容都是我干的扮授。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼专肪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼刹勃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嚎尤,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤深夯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后诺苹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咕晋,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年收奔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掌呜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡坪哄,死狀恐怖质蕉,靈堂內(nèi)的尸體忽然破棺而出势篡,到底是詐尸還是另有隱情,我是刑警寧澤模暗,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布禁悠,位于F島的核電站,受9級(jí)特大地震影響兑宇,放射性物質(zhì)發(fā)生泄漏碍侦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一隶糕、第九天 我趴在偏房一處隱蔽的房頂上張望瓷产。 院中可真熱鬧,春花似錦枚驻、人聲如沸濒旦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)尔邓。三九已至,卻和暖如春锉矢,著一層夾襖步出監(jiān)牢的瞬間梯嗽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工沈撞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慷荔,地道東北人雕什。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓缠俺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贷岸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子壹士,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 常見的一些設(shè)計(jì)模式 構(gòu)造函數(shù)模式(Constructor) 工廠模式(factory) 工廠模式和構(gòu)造函數(shù)模式每次...
    DeeJay_Y閱讀 357評(píng)論 0 0
  • 一、設(shè)計(jì)模式的起源 最早提出“設(shè)計(jì)模式”概念的是建筑設(shè)計(jì)大師亞力山大Alexander偿警。在1970年他的《建筑的永...
    冰凡513閱讀 331評(píng)論 0 0
  • 1.單例模式 定義: 單件模式確保一個(gè)類只有一個(gè)實(shí)例躏救,并提供一個(gè)全局訪問點(diǎn). 使用場(chǎng)景: 用于創(chuàng)建獨(dú)一無二的,只能...
    好奇而已閱讀 452評(píng)論 0 0
  • 問答 1.寫出構(gòu)造函數(shù)模式螟蒸、混合模式盒使、模塊模式、工廠模式七嫌、單例模式少办、發(fā)布訂閱模式的范例。 工廠模式诵原,想造什么造什么...
    GarenWang閱讀 365評(píng)論 0 0
  • 寫出 構(gòu)造函數(shù)模式英妓、混合模式挽放、模塊模式、工廠模式蔓纠、單例模式辑畦、發(fā)布訂閱模式的范例。 使用發(fā)布訂閱模式寫一個(gè)事件管理器...
    coolheadedY閱讀 340評(píng)論 0 0