【问题标题】:How to prevent overwriting context this in ES6 [duplicate]如何防止在 ES6 中覆盖上下文 this [重复]
【发布时间】:2016-01-05 23:42:00
【问题描述】:

How to prevent jquery to override "this" 非常相似,但在 ES6 中。

这是我的课:

class FeedbackForm {
  constructor(formEl) {
    this.$form = $(formEl)
    this.$form.submit(this.sendStuff)

    this.alerts = $('#something');
  }

  /**
   * Sends the feedback
   * @param {Event} e
   */
  sendStuff(e) {
    e.preventDefault()

    if (this.alerts.length) {
      window.alert('Notice... stuff')
    }

    $.ajax({
      type: this.$form.prop('method'),
      url: this.$form.prop('action'),
      data: this.$form.serialize()
    }).done(() => window.location.reload(true))
  }
}

sendStuff 方法是表单的事件处理程序,我相信 jQuery 使用Function.prototype.apply 调用它。因此,sendStuff 中的 this 被 jQuery 应用的事件目标覆盖,我无法访问 this.alerts 或任何其他属性方法。

我不确定是否可以在此处应用 var that = this 技巧或如何解决此问题?

【问题讨论】:

    标签: javascript jquery ecmascript-6 this jquery-events


    【解决方案1】:

    您可以使用arrow function

    与函数表达式相比,箭头函数表达式(也称为胖箭头函数)具有更短的语法并在词法上绑定 this 值

    应该这样做:

    this.$form.submit(e => this.sendStuff(e));
    

    【讨论】:

      【解决方案2】:

      您可以使用符号将FeedbackForm 实例与表单元素相关联。

      然后,在事件监听器内部,thise.currentTarget 将成为表单元素。使用您检索FeedbackForm 实例的符号。

      const myFeedbackForm = Symbol();
      class FeedbackForm {
        constructor(formEl) {
          formEl[myFeedbackForm] = this;
          this.$form = $(formEl);
          this.$form.submit(this.sendStuff);
          this.alerts = $('#something');
        }
        sendStuff(e) {
          e.preventDefault()
          if (this[myFeedbackForm].alerts.length) {
            window.alert('Notice... stuff')
          }
        }
      }
      new FeedbackForm(document.forms[0]).$form.submit();
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <form></form>
      <div id="something"></div>

      限制是您不能将同一个表单元素与不同的FeedbackForm 实例相关联。

      【讨论】:

      • 这也是一个有趣的方法,但箭头函数有效,这里的其他开发人员同意它更具可读性。
      【解决方案3】:

      尝试在主函数的两个函数范围之外初始化第二种存储变量:

      var that;
      class FeedbackForm {
      
        constructor(formEl) {
          this.$form = $(formEl)
          this.alerts = $('#something');
          that = this;
      
          this.$form.submit(this.sendStuff)    
        }
      
        /**
         * Sends the feedback
         * @param {Event} e
         */
        sendStuff(e) {
          e.preventDefault()
      
          if (that.alerts.length) {
            window.alert('Notice... stuff')
          }
      
          $.ajax({
            type: that.$form.prop('method'),
            url: that.$form.prop('action'),
            data: that.$form.serialize()
          }).done(() => window.location.reload(true))
        }
      }
      

      【讨论】:

      • 当我尝试转换时,Babelify 因语法错误而崩溃,因为我认为这是不允许的:“类主体只能包含方法,但不能包含数据属性。” 2ality.com/2015/02/es6-classes-final.html
      • 我已经编辑了我的答案。也许在课堂之外?抱歉,我想我是在黑暗中拍摄。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      • 2011-04-26
      • 1970-01-01
      • 2022-01-16
      相关资源
      最近更新 更多