TypeError: this is undefined

  • Creator 版本:v2.2.1

  • 目标平台: web

  • 详细报错信息,包含调用堆栈:

TypeError: this is undefined
    ClickCountMediator.ts:29:4   
    clickCallback ClickCountMediator.ts:29
    emit callbacks-invoker.js:344
    _doDispatchEvent CCNode.js:558
    dispatchEvent CCNode.js:1987
    _mouseUpHandler CCNode.js:472
    _callback CCEventListener.js:354
    _onListenerCallback CCEventManager.js:1023
    _dispatchEventToListeners CCEventManager.js:627
    dispatchEvent CCEventManager.js:1014
    registerSystemEvent CCInputManager.js:477

ClickCountView.ts 源码:

const { ccclass, property } = cc._decorator;
@ccclassexport default class ClickCountView extends cc.Component {  @property(cc.Label) label: cc.Label = null;
  @property(cc.Button) button: cc.Button = null;
  @property value: number = 0;
  onLoad() {    this.label = this.node.getChildByName("label").getComponent(cc.Label);    this.button = this.node.getChildByName("add").getComponent(cc.Button);    this.value = 0;  }
  start() {}
  public setButtonCallback(callback: any): void {    this.button.node.on(cc.Node.EventType.TOUCH_END, callback);  }
  public setNumber(count : number){    this.label.string = `count is : ${count}`;  }}

ClickCountMediator.ts 源码:

export class ClickCountMediator extends puremvc.Mediator {  private clickCountView: ClickCountView = null;  private clickCount: number = 0;
  constructor(mediatorName?: string, viewComponent?: any) {    super(mediatorName, viewComponent);
    this.clickCount = 0;    if (viewComponent == null) {      return;    }
    this.clickCountView = (viewComponent as cc.Node).addComponent(      ClickCountView    );    this.bindListener();  }
  private bindListener(): void {    this.clickCountView.setButtonCallback(this.clickCallback);  }
  private clickCallback() {    this.clickCount += 10;    this.sendNotification(CommandName.ClickCountCommand, this.clickCount);  }
  public listNotificationInterests() {    return [MediatorName.MediatorClickCount];  }
  public handleNotification(notification : puremvc.INotification){    switch(notification.getName()){      case MediatorName.MediatorClickCount:{        let clickCountRepository : ClickCountRepository = notification.getBody();        this.clickCountView.setNumber(clickCountRepository.count);        break;      }    }  }}

我是在 ClickCountMediator.ts 中调用 ClickCountView.ts 中的 button 绑定事件,但是在 ClickCountMediator.ts 的回调函数中,出现了错误。显示 TypeError: this is undefined,请问下,这个情况怎么处理?

ClickCountView.ts 源码:

ClickCountMediator.ts 源码:

论坛的编辑器有点不会用,见谅!

估计是到callback的时候 this 不知道指到那个去
可以参考这篇
估计是你在node.on( cc.Node.EventType>TOUCH_END, callback , 这个callback function的节点);
多传一个参数指定再这callback this是什么
不然就是再ClickCountMediator
oLoad或start 的时候用一个变数把自己记起来 例如 self = this 再callback 内把this 改成self

调用cc.Node.prototype.on居然不传target,该打

用闭包self会有问题的,会导致这个界面打开一次回调变多一个,直到你监听的Node被destory。
这个参数不仅仅解决一个this绑定的问题,还有生命周期的问题呢
调用on和once,还是提倡甚至可以硬性规定,必须传target

嗯嗯 你说的对
没仔细想清楚
还是传target比较好:grinning:

其实传 target 我也试过,但是具体不知道传哪个 target。
我之前是这样写的

ClickCountMediator.ts

  private bindListener(): void {    this.clickCountView.setButtonCallback(this.clickCallback, this);  }
  public setButtonCallback(callback: any, target : any): void {    this.button.node.on(cc.Node.EventType.TOUCH_END, callback, target);  }

这样的话,会报 TypeError: ClickCountMediator_1 is null 这个错

顺便说下,我用的是puremvc模式,Mediator是数据层的,View是表现层。每个Mediator包含了一个或者多个View,调用View的接口实现的界面更新的

你可以在setButtonCallback的时候就让外面把target传过来呀

ClickCountMediator.ts

private bindListener(): void { this.clickCountView.setButtonCallback(this.clickCallback, this); }
[/quote]
他看起来已经传了
看不太出来错在哪

这个有点毛病,程序有时候是正常在跑的,有时候又出问题。打印看执行顺序又是对的。

拥抱unity,,,,,

我就是从Unity过来的

我估计还有个可能 你是在constructor setbuttonclick 的 会不会是建构顺序问题
ClickCountMediator这个还没建立就去setbuttonclick 了
可以参考这边强制更改顺序
不然就是改一下写法改在start 都读取完后在处理应该也可行