[英]How to create 2 `this` reference in javascript from within a function
我有问题让我的代码工作,因为我试图将其分解为更小的方法因为this
引用。 我的代码如下:
const pageObject = {
/* set listener to get id of the radio input and then do something with it*/
onChange() {
// `this` here refers to the pageObject
console.log(this);
$('.radio input[type="radio"]').on('click', function() {
// `this` here refers to the radio input
console.log(this);
let $id = $(this).data('id');
// Error because `this` is referencing the radio input and not the pageObject.
this.doSomething($id);
}
},
/* just does something */
doSomething($id) {
return ...
}
}
// just calls the method on object so we can get started
pageObject.onChange();
我还想避免使用es6的arrow-functions () =>
和self = this
技术,如果可能的话,如YDKJS:This&Object Prototypes中推荐的那样 。
有没有一种方法来.bind()/.call()/.apply()
方法onChange()
引用this
到哪个引用pageObj
,也是this
其中引用收音机输入?
如有必要,请随意重新安排代码。 谢谢,期待!
更新
感谢下面建议的event.target
,这是一个有效的代码块:
const pageObject = {
/* set listener to get id of the radio input and then do something with it*/
onChange() {
// `this` here refers to the pageObject
console.log(this);
let radioHandler = function radioHandler(event) {
// `this` here also refers to the pageObject too since we are about to call this function via .bind()
console.log(this);
// use event.target here instead. sweet stuff.
let $id = $(event.target).data('id');
// doSomething() now works!
this.doSomething($id);
}
$('.radio input[type="radio"]').on('click', radioHandler.bind(this));
},
/* just does something */
doSomething($id) {
return ...
}
}
// just calls the method on object so we can get started
pageObject.onChange();
更新2
如何访问正确的this
回调里面? 正如@gyre在下面的评论中所提出的,提供了如何控制this
详细信息,但根本没有提到event.target
。 无论如何,这里是Event.target上的MDN Docs
您可以使用event.target
或event.currentTarget
来调用元素事件。 javascript
还缺少一个右)
在.on()
调用。
$('.radio input[type="radio"]').on('click', function(event) {
// `this` here refers to the radio input
let $id = $(event.target).data('radioId');
// Error because `this` is referencing the radio input and not the pageObject.
this.doSomething($id);
})
只需转换旧样式并将其设置为其他内容。
const pageObject = { /* set listener to get id of the radio input and then do something with it*/ onChange() { // `this` here refers to the pageObject console.log(this); const self = this; $('.radio input[type="radio"]').on('click', function() { // `this` here refers to the radio input console.log(this); let $id = $(this).data('id'); // Error because `this` is referencing the radio input and not the pageObject. self.doSomething($id); }; }, /* just does something */ doSomething($id) { return ... } } // just calls the method on object so we can get started pageObject.onChange();
在那种特殊情况下,你不需要在事件处理程序中使用this
,你可以有一个事件参数并使用event.target
,如:
const pageObject = { /* set listener to get id of the radio input and then do something with it*/ onChange() { // `this` here refers to the pageObject console.log(this); $('.radio input[type="radio"]').on('click', (event) => { // `this` here refers to the radio input console.log(event.target); let $id = $(event.target).data('id'); // Error because `this` is referencing the radio input and not the pageObject. this.doSomething($id); }; }, /* just does something */ doSomething($id) { return ... } } // just calls the method on object so we can get started pageObject.onChange();
更深入...
const pageObject = { /* set listener to get id of the radio input and then do something with it*/ onChange() { // `this` here refers to the pageObject console.log(this); $('.radio input[type="radio"]').on('click', this.onRadioClick.bind(this)) ; }, onRadioClick(event) { // `this` here refers to the radio input console.log(event.target); let $id = $(event.target).data('id'); // Error because `this` is referencing the radio input and not the pageObject. this.doSomething($id); }, /* just does something */ doSomething($id) { return ... } } // just calls the method on object so we can get started pageObject.onChange();
你会经常遇到这个和类似的问题。 根据需要,我可以通过两种方式解决它:使用闭包或绑定。
使用闭包在像你这样的情况下工作得很好,你在这里设置一个事件并在同一个父函数中定义事件处理程序。 您可以利用子函数可以访问父函数变量并访问屏蔽形式的事实
const pageObject = {
/* set listener to get id of the radio input and then do something with it*/
onChange() {
const parent = this
// 'parent and `this` here both refer to the pageObject
// 'parent' masks an instance of 'this' which can be accessed via closures
console.log('parent, this: ', parent, this);
$('.radio input[type="radio"]').on('click', function() {
// `this` here refers to the radio input
console.log(this);
let $id = $(this).data('id');
// 'parent' accesses parent 'this' thanks to closures and masking
parent.doSomething($id);
}
},
/* just does something */
doSomething($id) {
return ...
}
}
// just calls the method on object so we can get started
pageObject.onChange();
另一种方法使用bind。 当你想在一个函数中设置一个eventListener来调用在别处定义的处理函数但需要来自设置监听器的函数的'this'上下文的信息时,这个特别有用。 您可以使用它将代码分解为甚至小功能。
使用您的示例的示例可能如下所示:
const pageObject = {
/* set listener to get id of the radio input and then do something with it*/
onChange() {
// `this` refers to the pageObject
console.log(this);
// creates radio onClick eventListener
// assigns handleRadio function as event handler
// binds pageObject 'this' context for use in event handler
$('.radio input[type="radio"]').on('click', this.handleRadio).bind(this);
},
// separated event handler function to show how this works in more modular code.
handleRadio(e) {
// use e.target to give you the context for the click event
// use 'this' to access the pageObject 'this' context
console.log('e.target, this: ', e.target, this);
// still accesses pageObject 'this' due to the eventListener bind
let $id = $(this).data('id');
// No error
this.doSomething($id);
},
/* just does something */
doSomething($id) {
return ...
}
}
// just calls the method on object so we can get started
pageObject.onChange();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.