前端工程師必須掌握的設計模式

構造函數模式 —— Constructor

構造函數相信你們都不會陌生
在JS裏,咱們對構造函數使用new新增實例閉包

核心

1.將屬性綁定到this
2.將方法綁定到prototype
3.使用new新增實例【建立不一樣的引用類型函數

案例

function People() {
    this.name = '人'
}

People.prototype.walk = function () {
    console.log('walk')
}

let xiaoming = new People()

工廠模式 —— Factory

顧名思義,工廠模式就是像是工廠同樣流水線般生產處一個個對象this

核心

1.return一個對象
2.建立不一樣的引用類型prototype

案例

function createPerson() {
    // 定義工廠
    let person = {
        name: '人',
        walk: function () {
            console.log('walk')
        }
    }
    
    return person // 返回一個對象
}

let xiaoming = createPerson() // 工廠生產對象

單例模式 —— Singleton

核心

1.產生一個類的惟一實例
2.好處就是節約內存code

案例

function createPeople() {
    let name
    return function (userName) {
        return name || (name = userName)
    }
}

let single = createPeople()
console.log(single('人')) // '人'
// 無論再傳遞任何值,也只會返回 '人'
console.log(single('馬')) // '馬'

混合模式 —— Mixin

核心

1.在JS中,通常咱們實現繼承的過程就是混合模式
2.其概念就是提供可以被一個或者一組子類簡單繼承功能的類對象

案例

function People(name, age) {
    this.name = name
    this.age = age
}

People.prototype.sayName = function () {
    console.log(this.name)
}

function Student(name, age, score) {
    People.call(this, name, age)
    this.score = score
}

function create(prototypeObj) {
    let empty = function () {}
    empty.prototype = prototypeObj
    return new empty()
    // return值以下
    // {
    //     __proto__:prototypeObj
    // }
}

Student.prototype = create(People.prototype)

Student.prototype.work = function () {
    console.log('work')
}

模塊模式 —— Module

核心

在js中,經常使用閉包的形式來實現繼承

案例

let Person = (function () {
    let name = '小明'
    function sayName() {
        console.log(name)
    }

    return {
        name: name,
        sayName: sayName
    }
})()

發佈訂閱模式 —— Publish/Subscribe

核心

好比我【訂閱者】如今訂閱了一個公衆號,公衆號【發佈者】向我發佈消息事件

案例

實現一個jQuery的發佈訂閱案例內存

// 訂閱者
$('div').on('click',function () {})

// 發佈者
$('header').on('click',function () {
    $('div').trigger('click')
})

代碼io

let EventCenter = (function () {
    let events = {}

    function on(evt, handler) {
        // 實現監聽效果

        // 使用'或'是爲了能夠對同一個事件屢次進行回調
        events[evt] = events[evt] || []
        events[evt].push({
            handler: handler
        })
    }

    function fire(evt, args) {
        if (!events[evt]) {
            // 若是未監放任何事件,直接中斷
            return
        }
        for (let i = 0; i < events[evt].length; i++) {
            // 遍歷,實現對同一個事件的屢次回調
            events[evt][i].handler(args)
        }
    }

    function off(name) {
        delete events[name]
    }

    return {
        on: on, // 訂閱者
        fire: fire, // 發佈者
        off: off // 取消訂閱
    }
})()

EventCenter.on('hello', function (num) {
    console.log(num)
})
EventCenter.on('hello', function (num) {
    console.log(num)
})

EventCenter.fire('hello', 1) // 1[出現兩次]
相關文章
相關標籤/搜索