【问题标题】:How can I access a method from a closure?如何从闭包中访问方法?
【发布时间】:2018-11-21 02:02:26
【问题描述】:

寻求一些关于在闭包函数中修改对象的问题的指导。 我正在用 Angular 5 重写一个程序。我的程序使用商店来管理表单向导,其中一些问题使用 svg 元素/按钮来回答。单击后,将设置对象属性。下面的代码是我遇到的问题的骨架版本。

我已阅读其他关闭帖子,但没有遇到适合我的情况的帖子。

感谢您提供重构的答案和/或建议。

class Builder {
  object:any;

  constructor(){
    this.object = {
       car:'blue'
    }
  }

  init(){
    //Short cutting to click commands.. Using lodash
    _.forEach(database, (o)=>{
      console.log(this.object.car); // 'blue' to console
      ((function(){
         button.click(function(){
            this.object.car = 'red';
            console.log(this.object.car); //Cannot read property 
                                              'object' of undefined
         });

       })(),false)
    }
  }

}

更新原帖

我认为我需要在我的问题中为可能遇到此问题的其他人添加更多信息。我提供的代码是我整个代码的骨架。

在测试之前,我确实使用 ()={} 箭头符号(以不同的组合)重构了 function() 调用,但这并没有解决问题,因为它进一步破坏了需要 (this).element 的方法,因为button.click().

【问题讨论】:

  • 你的错误对我来说看起来很奇怪。如果之前的赋值不抛出,this怎么会是未定义的呢?
  • @ASDFGerte,也许 OP 假设 Cannot read property 'object' of undefined 来自 console.log(this.object.car); 行,而它实际上来自 this.object.car = 'red';,因为很可能这条线会抛出同样的错误。
  • 要保留对this 的引用,您可以将每次出现的function() {...} 替换为箭头函数() => {...}
  • @lealceldeiro 虽然两者都会抛出 TypeError 并且规范似乎没有说明所述错误的消息应该是什么,但这是可能的。但是,chrome、FF 和 node 都显示了可区分这些情况的正确消息,这使得他显示的错误极不可能来自该代码(连同声明,唯一可能引发此错误的其他地方应该记录“蓝色")。

标签: javascript angular closures store


【解决方案1】:

这里的一种方法是如果您将this 作为参数传递,例如

   ((function(that){
     button.click(function(){
        that.object.car = 'red';
        console.log(that.object.car);
     });

   })(this),false)     // <--  pass 'this' here

使用保留this 的箭头函数,您可以执行类似的操作

    console.log(this.object.car); // 'blue' to console
    button.click(() => {
        this.object.car = 'red';
        console.log(this.object.car);
    });

【讨论】:

  • 需要得到this 作为这样的参数:((function(that){ ... })(this),false)
  • 或者 OP 可以使用箭头函数代替,它保留了this
  • @user184994 也许是这样,而且由于我不是箭头函数方面的专家,所以替换 闭包 时这些函数的工作/外观如何?
  • 只需将function () 替换为() =&gt;
  • ... 并删除 IIFE。
【解决方案2】:

感谢大家的评论和提交的答案。我想声明@LGson 提供的答案是一个可靠的答案并且有效。但我觉得我需要稍微清理一下这篇文章并分享我为解决这个问题所做的工作,我的情况是使用画布框架生成依赖于 button.click() 中元素的 (this) 的 UI 元素事件以及我无法访问外部对象的地方。

这就是我如何让它发挥作用的方法。

  1. 我将外部函数更改为箭头符号格式并离开 问题中所述的 button.click() 调用。
  2. 我为 self 添加了一个变量,它指向我需要的对象 访问。
  3. 我在对象中添加了一个 getter 方法来返回 需要内部引用并使用 self.car 和 self.getter 来设置 并检索我需要的值。和库方法 继续按预期工作。

    class Builder {
     object:any;
    
     constructor(){
      this.object = {
        car:'blue',
        get value():{ return this.car;}
       }
      }
    
     init(){
      var self = this.object;
    
      _.forEach(database, (o)=>{
      console.log(this.object.car); // 'blue' to console
      ((()=>{
        button.click(function(){
             self.car = 'red';
             console.log(self.value); // red
    
        });
    
       })(),false)
    

    } } }

【讨论】:

    猜你喜欢
    • 2017-04-08
    • 2016-11-30
    • 2014-02-26
    • 2018-11-13
    • 2015-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    相关资源
    最近更新 更多