SAPUI5中传函数作为MessageBox参数时提前执行报错问题
问题原因
你遇到的异常属于典型的JavaScript回调函数传递错误,对应根因如下:
- 弹窗打开就打印日志、点击时报
TypeError: fnDo is not a function:本质是把函数执行结果而非函数本身当作参数传递了。最常见的写法错误是给回调函数名后加了执行括号(),导致代码运行到参数解析阶段(弹窗初始化时)就立刻执行对应函数,此时foo接收到的参数是bar执行后的返回值undefined(bar无显式返回值),后续点击触发时调用fnDo()就相当于执行undefined(),直接抛出类型错误。 - 你贴出的示例代码存在对象方法间缺少逗号分隔的语法问题,JS引擎无法正常解析对象字面量,运行时会直接报错,需要补充分隔逗号。
- 额外隐患:直接传递
this.bar作为参数时会丢失函数的this绑定,如果后续bar方法内需要访问控制器的属性、其他方法,会出现this指向错误。
正确实现代码
foo: function(fnDo) { // 如需保证fnDo内部this指向控制器,可通过call绑定上下文 fnDo.call(this); }, bar: function() { console.log("foobar"); }, onMessageBoxshow: function(sMessage) { MessageBox.warning(sMessage, { actions: ["Proceed", "Cancel"], // 用箭头函数定义onClose,自动继承外层控制器的this指向 onClose: (sAction) => { if (sAction === "Proceed") { // 写法1:通过bind绑定this后传递函数本身,不会提前执行 this.foo(this.bar.bind(this)); // 写法2(逻辑复杂时更推荐):用箭头函数包裹执行逻辑,可读性更高,完全避免this丢失问题 // this.foo(() => { // this.bar(); // }); } } }); }
注意事项
- 传递回调函数时,不要在函数名后加
(),加括号代表立即执行函数,传入的是执行结果而非函数本身。 - 不建议在
onClose回调里用普通function定义,否则内部this会指向MessageBox配置对象而非控制器,找不到挂载在控制器上的foo、bar方法。如果一定要用普通函数,需要在外层提前缓存控制器实例:onMessageBoxshow: function(sMessage) { const oController = this; // 提前缓存控制器实例 MessageBox.warning(sMessage, { actions: ["Proceed", "Cancel"], onClose: function(sAction) { if (sAction === "Proceed") { oController.foo(oController.bar.bind(oController)); } } }); }
内容的提问来源于stack exchange,提问作者Alpha
相关产品推荐
相关产品推荐

