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