由于种种原因,我需要自己实现一个类似EventTarget的类
是这样的

然后我在另一个类里继承了这个类

这样,其他人就可以在这个networkconnection上注册消息了
但是在触发事件的时候

报错了
这个看起来像是系统认为我在调用EventTarget的那个dispatchEvent
这是怎么回事,我的lsEventgHandler没有继承cc.Node啊,怎么会去调用EventTarget的函数呢?
由于种种原因,我需要自己实现一个类似EventTarget的类
是这样的

然后我在另一个类里继承了这个类

这样,其他人就可以在这个networkconnection上注册消息了
但是在触发事件的时候

报错了
这个看起来像是系统认为我在调用EventTarget的那个dispatchEvent
这是怎么回事,我的lsEventgHandler没有继承cc.Node啊,怎么会去调用EventTarget的函数呢?
应该跟类的继承没有关系。你应该有一个把onSocketOpen传给别的函数调用的地方,传入时,把传入的this.onSocketOpen改成
this.onSocketOpen.bind(this);
//或者
()=>{this.onSocketOpen()}
这样你的onSocketOpen执行的时候,内部的this才是正确的this,否则可能指向的是全局的window对象,window.dispatchEvent是浏览器自带的函数。
多谢指正!
搞定了,这个this真坑啊
是
this.mSocket.addEventListener("message", this.onReceiveMessage.bind(this));
多谢!没问题了
就是说this.onReceiveMessage.bind(this)会产生一个新的函数实例吗?
跟this.onReceiveMessage不是一个了?
我又遇到一个奇怪的问题,求大神指点~~
上面代码里,for循环中,如果我直接写this.mEventMap[eventName] 就会提示
![]()
注意上面那个lsLog.i都把this.mEventMap[eventName].Func打印出来了
但是如果我把this.mEventMap[eventName] 替换成上面的变量ev,就能运行过去
mEventMap[eventName] 的类型是这个

这两种情况难道不等价吗
这是什么情况?@toddlxt
可能你循环体里面对this.mEventMap重新赋值了?导致重新赋值后this.mEventMap[eventName]不存在。而ev已经指向了原来存在的this.mEventMap[eventName],所以this.mEventMap怎么变化都没事。
循环体里是可以继续用this.mEventMap[eventName]不会报错,唯独for的括号里不能用。。。
可能是不等价的, 你对比下 ts 转换后的 js 代码看看, 位于 temp/quick-scripts/assets 同样的目录中.
你把循环体截全了看吧。
import lsLog from “…/Log/Log”;
export class lsEvent
{
public EventName : string;
public Func : Array<((data : any) => void)>;
public touch(data : any) : void
{
for (let i = 0; i < this.Func.length; i++)
{
try
{
this.Func[i](data);
}
catch (e)
{
lsLog.w("event: " + this.EventName + " runtime error: " + e);
}
}
}
}
export default class lsEventHandler
{
protected mEventMap : Object = null;
protected mName : string;
constructor(name : string)
{
this.mName = name;
this.mEventMap = new Object();
}
public hasEvent(eventName : string) : boolean
{
return this.mEventMap.hasOwnProperty(eventName);
}
public dispatchEvent(eventName : string, data : any) : void
{
if (this.mEventMap.hasOwnProperty(eventName))
{
let ev : lsEvent = this.mEventMap[eventName];
ev.touch(data);
}
else
{
lsLog.w(“event: " + eventName + " does’t exist.”)
}
}
public registerEvent(eventName : string, caller : any, callbackFunc : ((data : any) => void)) : any
{
let ev : lsEvent = null;
if (!this.mEventMap.hasOwnProperty(eventName))
{
ev = new lsEvent();
ev.EventName = eventName;
ev.Func = new Array<((data : any) => void)>();
this.mEventMap[eventName] = ev;
}
else
{
ev = this.mEventMap[eventName];
}
let newFunc = callbackFunc.bind(caller);
ev.Func.push(newFunc);
return newFunc;
}
public unregisterEvent(eventName : string, callbakcFunc : ((data : any) => void)) : void
{
if (this.mEventMap.hasOwnProperty(eventName))
{
lsLog.i("name: " + this.mName);
lsLog.i(this.mEventMap[eventName].Func);
let ev : lsEvent = this.mEventMap[eventName];
let ilen = this.mEventMap[eventName].Func.length;
// ------------------------------------------------------------------------------------------------------------
// 这里如果吧ilen直接写成this.mEventMap[eventName].Func.length就有问题
// *************************************************************************************************************
for (let i = 0; i < ilen; i++)
{
//这里用this.mEventMap[eventName].Func也没问题
if (this.mEventMap[eventName].Func[i] == callbakcFunc)
{
ev.Func.splice(i, 1);
if (ev.Func.length == 0)
{
delete this.mEventMap[eventName];
}
}
}
}
else
{
lsLog.w(“event: " + eventName + " does’t exist.”)
}
}
}
js文件我看过。。。基本上跟ts没区别。。。
不就是我说的那样吗?你在循环体里delete this.mEventMap[eventName]了,下一次循环前判断i < this.mEventMap[eventName].Func.length时,this.mEventMap[eventName]就不存在了呀?
。。。。。。
我还想着这个for不是每次循环都取一次呢
多谢多谢
bind会产生新函数,可以试试用apply执行
确实如此, 每次循环都会取一遍, 没有反应过来…