前端js自定义对象与自定义事件的实现

前端js自定义对象与自定义事件的实现

    • 应用场景
    • 自己实现一个简单的事件管理器

应用场景

当你要写一些库之类的东西,通常需要构造一个巨大的对象,对象的方法经常互相穿插,这时可以使用自定义事件去解耦,使程序结构更清晰易于开发和维护。

自己实现一个简单的事件管理器

有同学说直接用jq里的不就行了?
当你写一个库的时候,把整个jq添加进去,jq其他的功能你又不想用,对于库来说就像城市的CBD,寸土寸金。不可能加一堆没用的东西在里面,所以只能参考其他代码自己完成一个。

class EventManager {
            constructor() {
                this.container = {}
            }
            addEvent(type, fn) {
                if (typeof type === "string" && typeof fn === "function") {
                    if (!this.container[type]) {
                        this.container[type] = [fn]
                    } else {
                        this.container[type].push(fn)
                    }
                }
                return this
            }
            fireEvent(type) {
                if (type && this.container[type]) {
                    // var args = Array.prototype.slice.call(arguments)
                    let args = [...arguments]
                    // var args = Array.from(arguments)
                    args.shift()

                    const length = this.container[type].length
                    for (let i = 0; i < length; i++) {
                        let fun = this.container[type][i]
                        fun.apply(this, args)
                    }
                }
                return this
            }
            removeEvent(type, key) {
                if (typeof key !== "function" || typeof type !== "string") {
                    return
                }
                let listeners = this.container[type]
                if (Array.isArray(listeners) && listeners.length) {
                    for (let i = 0; i < listeners.length; i++) {
                        if (listeners[i] === key) {
                            listeners.splice(i, 1)
                            break
                        }
                    }
                } else {
                    delete this.container[type]
                }
                return this
            }
        }

        class AAA extends EventManager {
            constructor (name) {
                super()
                this.name = name
            }
        }

        let aaa = new AAA('aaa')

        function a11(p1,p2,p3) {
            console.log(this)
            console.log(p1,p2,p3)
        }
        function a22(p1,p2,p3) {
            console.log(this)
            console.log(p1,p2,p3)
        }

        aaa.addEvent('testEvent', a11)
        aaa.addEvent('testEvent', a22)
        // aaa.removeEvent('testEvent', a11)

        aaa.fireEvent('testEvent',44,55,66)

这样就实现了一个简单的自定义事件管理器,其实并不是真正意义的前端事件,纯粹就是一个发布订阅模式解耦代码用的东西。
如果看不懂的话放到浏览器debugger一下,单步调试一定能看懂的。

为什么不能直接用web API里的事件相关的API实现呢?
普通对象不是EventTarget类的实例,所以不能使用事件相关的方法。
继承一下应该就能用了。

let event1 = new Event('event1')

class AAA extends EventTarget {
	constructor(name) {
		super()
		this.name = name
		this.variable = 0
	}
}

let aaa = new AAA('aaa')

let listener1 = function (event,param) {
	console.log(event)
	console.log(param)
	console.log(this)
}

let listener2 = function (event,param) {
	console.log(1)
}

aaa.addEventListener('event1',listener1)  //这里一定要用字符串'event1'
aaa.addEventListener('event1',listener2)
// aaa.removeEventListener('event1',listener) //这里一定要用字符串'event1'


aaa.variable = 1 //通过修改实例属性当作参数传递
aaa.dispatchEvent(event1,1)

经过测试,与我们自己实现的事件管理表现一致.并且触发的事件是一个真正的event对象.

前端js自定义对象与自定义事件的实现_第1张图片

但是dispatchEvent时,是不能够动态传参的,没办法只能在实例上定义个变量,共享参数的变化来变相传参.

你可能感兴趣的:(框架,库,javascript,js,chrome)