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个事件') ```

  

posted @ 2020-09-02 22:43  尽世间恶丑  阅读(190)  评论(0编辑  收藏  举报