
本人,后端开发人员,对 JS 了解不多。不知道标题是否准确。
出于自用目的,正在写一个 userscript。编写过程中遇到了一点障碍,奈何不知道应该如何表述,所以没法搜。
样例代码
class Foo { constructor() { this.field = new Map() } requestOnLoad(details) { /* * 此方法由于产生于回调 * 而 Javascript 中函数本身也属于对象 * 因此 * 此时的 this 代表的是 GM_xmlhttpRequest 方法所产生的回调函数 * 并不指向与 Foo 对象的实例 * * 但是,我希望在此方法内访问 Foo 对象的实例,并设置 field 属性 */ this.field.set('aa', 'bb') // 如何能够让这句话符合预期呢? } invoke() { GM_xmlhttpRequest({ url: requestUrl, method: "GET", onload: this.requestOnLoad, }); } } new Foo().invoke() 因此当样例代码执行时,this 指向的对象与预期不符,导致我没法调用 field.set 方法。同时,奈何我搜了一堆 ES6 相关资料。
也没见到有相关的解释。
请教各位前端大佬,对于样例代码中,requestOnLoad 方法内,应该如何正确的访问到 Foo 对象的实例呢?
1 wxsm 2018-11-30 14:02:07 +08:00 使用箭头函数。 requestOnLoad: (details) => { //... } |
2 imyxz 2018-11-30 14:04:57 +08:00 via Android 应该是这样吧(new Food()).invoke() |
3 wildnode 2018-11-30 14:12:11 +08:00 箭头函数可解 |
4 sker101 2018-11-30 14:12:13 +08:00 via iPhone onload 的函数试试.bind ( this ) |
5 gam2046 OP @wxsm 感谢。你是指这样调用嘛? GM_xmlhttpRequest({ url: requestUrl, method: "GET", onload: (details)=>{ /*Do something*/}, onerror: this.requestOnError, onabort: this.requestOnAbort, ontimeout: this.requestOnTimeout }); 但是有一点很尴尬的事情,按照我既往的经验,我设计的是,后面还有一个 class 会继承( extends )这个 Foo,因此 requestOnLoad 实际做的事情,并不在 Foo 里面定义。这样话,我就没法这么写了。是否还有其他变通方法呢? |
6 O3YwA1ENkb7i35XJ 2018-11-30 14:17:11 +08:00 GM_xmlhttpRequest({ url: requestUrl, method: "GET", onload: this.requestOnLoad.bind(this), }); @gam2046 onload: this.requestOnLoad.bind(this), |
7 gam2046 OP 感谢 @sker101 提供的方法。该方法可以解决我遇到的问题,顺便我去搜了下相关资料 https://developer.mozilla.org/en-US/docs/Web/Javascript/Reference/Global_Objects/Function/bind 解决方案: GM_xmlhttpRequest({ url: requestUrl, method: "GET", onload: this.requestOnLoad.bind(this) // 此时在回调方法中 this 对象即为 bind 方法中传递的对象 }); |
8 DrugsZ 2018-11-30 14:58:55 +08:00 constructor() { this.field = new Map() this.requestOnLoad= this.requestOnLoad.bind(this) } 这样好一点吧, |
9 SoloCompany 2018-11-30 21:36:05 +08:00 https://github.com/tc39/proposal-bind-operator 虽然有 babel 的实现, 却仍然是 stage 0 提案 onload: ::this.requestOnLoad |
10 TwoDays91 2018-11-30 22:18:11 +08:00 via iPhone 除了 bind 方法 onload: () => {this.requestonload()}也可以 |