如何防止在 ES6 中覆盖上下文 this
How to prevent overwriting context this in ES6
与 How to prevent jquery to override "this" 非常相似,但在 ES6 中。
这是我的 class:
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
技巧或者我该如何解决这个问题?
尝试从主函数内的两个函数的范围之外初始化第二种存储变量:
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))
}
}
您可以使用符号将 FeedbackForm
实例与表单元素相关联。
然后,在事件侦听器内部,this
或 e.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
实例相关联。
您可以使用 arrow function:
An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and lexically binds the this value
应该这样做:
this.$form.submit(e => this.sendStuff(e));
与 How to prevent jquery to override "this" 非常相似,但在 ES6 中。
这是我的 class:
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
技巧或者我该如何解决这个问题?
尝试从主函数内的两个函数的范围之外初始化第二种存储变量:
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))
}
}
您可以使用符号将 FeedbackForm
实例与表单元素相关联。
然后,在事件侦听器内部,this
或 e.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
实例相关联。
您可以使用 arrow function:
An arrow function expression (also known as fat arrow function) has a shorter syntax compared to function expressions and lexically binds the this value
应该这样做:
this.$form.submit(e => this.sendStuff(e));