关于aurelia-hammer中call函数及$event映射的技术咨询
咱们一步步来拆解这两个问题吧——我对JS的函数绑定和Aurelia的事件系统都摸得透透的,能给你讲清楚细节~
call()函数的工作机制 call()是所有函数都从Function.prototype继承来的核心方法,它的核心作用就是临时切换目标函数的this指向,同时立即执行该函数。
具体的工作流程可以拆成这几步:
- 当你调用
func.call(context, arg1, arg2, ...)时,首先会确定context的有效指向:如果传入的是null或undefined,非严格模式下this会自动绑定到全局对象(浏览器里是window,Node.js里是global);严格模式下则保持传入的null/undefined不变。 - 接下来,把
func内部的this指向替换成你传入的context。 - 然后,将
call()里除context之外的所有参数,按顺序传递给func作为它的执行参数。 - 最后执行
func,并返回函数执行的结果。
举个直观的例子帮你理解:
const user1 = { name: "Alice" }; const user2 = { name: "Bob" }; function greet(greeting) { console.log(`${greeting}, I'm ${this.name}`); } // 用call把greet的this绑定到user1,同时传入问候语参数 greet.call(user1, "Hello"); // 输出:Hello, I'm Alice // 切换绑定到user2 greet.call(user2, "Hi"); // 输出:Hi, I'm Bob
这里greet本身不属于任何对象,但通过call()可以让它临时“挂靠”到user1或user2上,从而正确访问this.name。
hammerEvent到Aurelia视图模型$event的映射过程 先看你提到的代码行:this.callback.call(null, { hammerEvent: event });,要搞懂映射逻辑,得结合Aurelia的事件绑定规则和这个插件的工作原理来看:
第一步:回调函数的来源
this.callback其实就是你在Aurelia视图里绑定的事件处理函数。比如你可能在模板里写了这样的代码:
<div press.delegate="handlePress($event)"></div>
当Aurelia解析这个绑定的时候,会把视图模型里的handlePress函数赋值给插件的this.callback,并且提前把handlePress的this绑定到视图模型实例——所以这里call(null)并不会影响handlePress内部的this指向,因为绑定工作已经提前完成了。
第二步:参数的传递与映射
当Hammer.js检测到press事件触发时,插件会调用this.callback.call(null, { hammerEvent: event }),这里传入的第二个参数{ hammerEvent: event }就是回调函数的第一个实参。
而在Aurelia的事件绑定规则里:
- 如果你在视图里用
$event作为参数,Aurelia会自动把回调函数接收到的第一个参数赋值给$event变量。 - 所以当
handlePress($event)被调用时,$event就等于插件传入的{ hammerEvent: event },你在视图模型里就能通过$event.hammerEvent拿到原始的Hammer事件对象了。
简单总结:插件把Hammer事件包装成一个对象传入回调,Aurelia直接把这个传入的对象映射到你在视图里声明的$event变量上。
内容的提问来源于stack exchange,提问作者Matthew Ellison

