[英]How to create 2 `this` reference in javascript from within a function
I have issues getting my code to work as I try to break it down into smaller methods because of the this
referencing. 我有问题让我的代码工作,因为我试图将其分解为更小的方法因为
this
引用。 My code is as follow: 我的代码如下:
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();
I also want to avoid using es6's arrow-functions () =>
and self = this
techniques if possible as recommended in YDKJS: This & Object Prototypes . 我还想避免使用es6的arrow-functions
() =>
和self = this
技术,如果可能的话,如YDKJS:This&Object Prototypes中推荐的那样 。
Is there a way to .bind()/.call()/.apply()
the method onChange()
to reference the this
which references to the pageObj
and also the this
which references to the radio input? 有没有一种方法来
.bind()/.call()/.apply()
方法onChange()
引用this
到哪个引用pageObj
,也是this
其中引用收音机输入?
Feel free to rearrange the code if necessary. 如有必要,请随意重新安排代码。 Thanks, looking forward!
谢谢,期待!
Update 更新
Thanks to event.target
as suggested below, here is a working code block: 感谢下面建议的
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();
Update 2 更新2
How to access the correct this
inside a callback? 如何访问正确的
this
回调里面? as suggested by @gyre in the comments below provides a great detail of how to control this
but doesn't mention event.target
at all. 正如@gyre在下面的评论中所提出的,提供了如何控制
this
详细信息,但根本没有提到event.target
。 Anyway, here is MDN Docs on Event.target 无论如何,这里是Event.target上的MDN Docs
You can use event.target
or event.currentTarget
to reference element event is dispatched to. 您可以使用
event.target
或event.currentTarget
来调用元素事件。 javascript
is also missing closing )
at .on()
call. 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);
})
Just go old style and set it to something else. 只需转换旧样式并将其设置为其他内容。
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();
In that particular case you don't need to use this
inside the event handler by the way, you can have an event parameter and use event.target
, like: 在那种特殊情况下,你不需要在事件处理程序中使用
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();
Even further... 更深入...
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();
You'll come across this and similar issues pretty often. 你会经常遇到这个和类似的问题。 Depending on the need, I solve it in one of two ways: using closures or binding.
根据需要,我可以通过两种方式解决它:使用闭包或绑定。
Using closures works well in cases like yours here where you're setting an event and defining the event handler in the same parent function. 使用闭包在像你这样的情况下工作得很好,你在这里设置一个事件并在同一个父函数中定义事件处理程序。 You can take advantage of the fact the the child functions can access parent function variables and access a masked form of this
您可以利用子函数可以访问父函数变量并访问屏蔽形式的事实
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();
Another method uses bind. 另一种方法使用bind。 This is particularly useful when you want to set an eventListener in one function that calls a handler function defined elsewhere but need information from the 'this' context of the function setting the listener.
当你想在一个函数中设置一个eventListener来调用在别处定义的处理函数但需要来自设置监听器的函数的'this'上下文的信息时,这个特别有用。 It you can use it to break down your code into even small functions.
您可以使用它将代码分解为甚至小功能。
An example using your example could look something like 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.