9.3 es6 class一部分 and es5 class 发布订阅
function Events(params) { this.events = [] } //订阅 Events.prototype.on = function (eventName,eventFn) { if(!this.events[eventName]) { //把事件存起来 ,有就push没有就创建新的 this.events[eventName] = [] } this.events[eventName].push(eventFn) } //发布 Events.prototype.emit = function (eventName,msg) { if(this.events[eventName]){ //如果找到了这个事件就执行 this.events[eventName].forEach(event => { //console.log(this.events) event(msg) }) } } //退订 Events.prototype.removeEve = function (eventName,eventFn) { console.log(eventFn) if (this.events[eventName]) { //移除传过来的那个回调的事件 this.events[eventName] = this.events[eventName].filter(event => { return event.name !== eventFn }) console.log(this.events) } } let e = new Events() e.on('say',function say(msg){ console.log("hello---"+ msg) }) e.on('sing',function sing(msg){ console.log("hello---"+ msg) }) e.on('eat',function eating(msg){ console.log("hello---"+ msg) }) e.on('eat',function eatmore(msg){ console.log("delete---"+ msg) }) // e.emit('say','say') // e.emit('sing','sing') // e.emit('eat','eat') e.removeEve('eat','eatmore') e.emit('say','say') e.emit('sing','sing') e.emit('eat','eat') e.emit('eat','删除eatmore') //输出 eatmore [ say: [ [Function: say] ], sing: [ [Function: sing] ], eat: [ [Function: eating] ] ] hello---say hello---sing hello---eat hello---删除eatmore
es5构造函数 ```javascript //原型 function Person(name) { this.name = name } Person.prototype.sayName = function (params) { console.log(this.name) } let person = new Person('name') person.sayName() //name ``` 所有实例共享sayname方法,通过原型继承 #### es6 class 1. 类的声明 ```javascript class Person1 { constructor(name) { // 相当于Person构造函数 this.name = name } sayName() { //相当于prototype.sayName console.log(this.name) } } let person1 = new Person1('nameclass') person1.sayName() //nameclass console.log(typeof Person1) //function ``` Person1就是创建了一个拥有constructor方法及其行为的函数,所以sayName就是Person1.prototype上的方法 2. class与构造函数的区别 1. 类声明不会提升,与let相似 2. 声明中的代码都处于严格模式,并且无法退出 3. 类的所有方法不可枚举(枚举,删除,可写,value默认属性要通过defineProperty) 4. 类的方法没有construct不能new 5. 类构造器也不能new 6. 类内部类名不能重写 3. ```javascript let PersonType2 = (function() { "use strict"; const PersonType2 = function(name) { // 确认函数被调用时使用了 new if (typeof new.target === "undefined") { throw new Error("Constructor must be called with new."); } this.name = name; } Object.defineProperty(PersonType2.prototype, "sayName", { value: function() { // 确认函数被调用时没有使用 new if (typeof new.target !== "undefined") { throw new Error("Method cannot be called with new."); } console.log(this.name); }, enumerable: false, writable: true, configurable: true }); return PersonType2; }()); ``` 相当于上面的代码所以在内部不能重写方法 在类外部可以 4. class也有表达式:也不会提升 ```javascript let Person = class { constructor(name) { // 相当于Person构造函数 this.name = name } sayName() { //相当于prototype.sayName console.log(this.name) } } let person = new Person() ``` 也可以具名 ```javascript let Person2 = class Person{ constructor(name) { // 相当于Person构造函数 this.name = name } sayName() { //相当于prototype.sayName console.log(this.name) } } typeof Person //undefined ``` 最终使用Person2,Person只在类内部定义存在 5. class可以被用作参数 ----和new合用 ```javascript function createObject(classobj) { return new classobj() } let obj = createObject( class { sayHi() { console.log('hi') } }) obj.sayHi() //立即执行 let newobj = new class { constructor(name) { this.name = name } sayName() { console.log(this.name) } }('立即调用构造器') newobj.sayName() ``` 6. 继承 ```javascript class People { constructor(name) { this.name = name } sayName() { console.log(this.name) } static sayHi() { console.log('静态方法') } } class Stu extends People { constructor(name) { super(name) } } //静态方法只能通过类调用,继承也只能通过当前继承类调用 let student = new Stu('学生') Stu.sayHi() // 静态方法 student.sayHi() //sayHi is not a function student.sayName() //学生 ``` 7. 类的发布订阅 ```javascript class Event { constructor() { this.events = [] } addEve (eventName,eventFn) { if(!this.events[eventName]) { //把事件存起来 ,有就push没有就创建新的 this.events[eventName] = [] } this.events[eventName].push(eventFn) } emit (eventName,msg) { if(this.events[eventName]){ //如果找到了这个事件就执行 this.events[eventName].forEach(event => { //console.log(this.events) event(msg) }) } } removeEve (eventName,eventFn) { //console.log(eventFn) if (this.events[eventName]) { //移除传过来的那个回调的事件 this.events[eventName] = this.events[eventName].filter(event => { return event.name !== eventFn }) console.log(this.events) } } }
class Eve extends Event {
} class Eve extends Event { constructor() { super() } } let event = new Eve() event.addEve('class1',function class1(msg){ console.log("class1---"+ msg) }) event.addEve('class2',function class2(msg){ console.log("class2---"+ msg) }) event.addEve('class3',function class3(msg){ console.log("class3---"+ msg) }) event.removeEve('class3','class3') event.emit('class1','第一个事件') // event.emit('class2','第2个事件')// event.emit('class3','第3个事件') ```