函数参数的直接传递和匿名传递

notifier():前端消息处理器,用来统一处理WebSocket消息。

notifier#attachMessageEvent:添加消息事件,参数为事件event

事件event:由各个控制器定义,不同controller内自己定义、实现。比如新建newProjectController、刷新updateController

添加方式:假设事件实现为notifierMessage,如果notifierMessage内代码有this(使用了controller中的对对象),则只能使用箭头函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// updateController类中
// 1. 箭头函数(匿名函数)
notifier().attachMessageEvent(message => {
this.notifierMessage(message);
});

// 2. 有引用的箭头函数(匿名函数)
this._messageFunction = message => {
this.notifierMessage(message);
};
notifier().attachMessageEvent(this._messageFunction);

// 3. 直接传递
notifier().attachMessageEvent(this.notifierMessage);

前两种:
this 关键字指的是箭头函数外部的 this 上下文,也就是定义 notifierMessage 方法的对象的上下文。
箭头函数继承了其外部作用域的 this 值,因此 this.notifierMessage 将引用正确的
notifierMessage 方法。
【第二种有个好处是可以获取到匿名函数,因为匿名函数有了一个引用this._messageFunction
通过this._messageFunction 即可获取这个匿名函数。比如需要notifier取消绑定该事件消息时,
需要根据引用,只能使用第二种方式】

最后一种:this 关键字同样指的是定义 notifierMessage 方法的对象的上下文。
但是,需要注意的是,在非严格模式下,当一个函数作为普通函数调用
时(而不是作为对象的方法),this 的值通常会被设置为
全局对象(在浏览器中是 window)。因此,如果没有明确绑定
this,notifierMessage 可能不会按照预期工作。
【因为是将event传递给notifier,后续由notifier调用,所以作为普通函数调用。】

区别总结

  • 代码片段一

    • 使用了一个箭头函数来包裹对 this.notifierMessage 的调用。
      • 保证了 this 的正确上下文,即使 notifierMessage 方法内部依赖于 this 的值。
  • 代码片段二

    • 直接传递 this.notifierMessage 方法给 attachMessageEvent
      • 如果 notifierMessage 内部依赖于 this 的值,并且该方法不是作为对象的方法被调用,可能会导致 this 的值不符合预期。

注意:

notifier 添加的事件是 controller中的函数,所以当controller对象被回收时(没有controller对象引用时)这个事件也就失效了。即**对象被垃圾回收以后,其他 引用该对象方法的 方法,也会失效。**比如,controller 被回收以后,notifier中注册的该 controller 的 this.notifierMessage 方法也失效了。