I'm getting the following warning when using jshint. Why?
If a strict mode function is executed using function invocation, its 'this' value will be undefined.
function demo() {
'use strict';
document.querySelector('#demo').addEventListener('click', test);
function test() {
console.log(this);
}
}
I'm getting the following warning when using jshint. Why?
If a strict mode function is executed using function invocation, its 'this' value will be undefined.
function demo() {
'use strict';
document.querySelector('#demo').addEventListener('click', test);
function test() {
console.log(this);
}
}
Share
Improve this question
edited Apr 17, 2018 at 16:37
Alvaro
asked Apr 17, 2018 at 16:27
AlvaroAlvaro
41.6k31 gold badges172 silver badges348 bronze badges
6
-
1
Because
this
will indeed beundefined
if you invoketest
without using some way to provide a definite thisArg. Sotest()
will give youundefined
for thethis
value. – user2437417 Commented Apr 17, 2018 at 16:31 -
You'll need to use
.call()
or.apply()
to passthis
to the function that's being called trough indirect invocation. I don't know why strict mode does that, but it does. – Phiter Commented Apr 17, 2018 at 16:32 -
1
It'll cause problems if you try to use
this
as an object (like trying to access properties). Not an issue in that specific function as written. Without strict mode, you're guaranteed an object. – user2437417 Commented Apr 17, 2018 at 16:34 - 1 I guess I'll have to configure jsHint to not fire those warnings? – Alvaro Commented Apr 17, 2018 at 16:36
- 1 Yeah, it's all configurable. jshint./docs/options/#validthis – user2437417 Commented Apr 17, 2018 at 16:36
3 Answers
Reset to default 3This works for me
function demo() {
'use strict';
var that = this; //new line
document.querySelector('#demo').addEventListener('click', test);
function test() {
console.log(that); //print that instead of this
}
}
Rather than try to suppress the warning, it's better to address the root cause.
Use of this
can be confusing, and the value of this
can unexpectedly change when refactoring code. Your code will be easier to read and maintain if you explicitly pass parameters.
The parameter passed to the test()
callback is the Event
object for the click:
function demo() {
'use strict';
function test(event) {
console.log('You clicked on:', event.target.outerHTML);
}
document.querySelector('#demo').addEventListener('click', test);
}
demo();
Console log output will be something like:
You clicked on: <h1 id="demo">Click Me</h1>
The Event
object tells you the target element that the user clicked:
https://developer.mozilla/en-US/docs/Web/API/Event/target
Fiddle with the code:
https://jsfiddle/24epdxbz/2
From yehudakatz:
The ECMAScript 5 spec says that
undefined
is (almost) always passed, but that the function being called should change itsthisValue
to the global object when not in strict mode. This allows strict mode callers to avoid breaking existing non-strict-mode libraries.
Sometimes the scope in JS needs that instead of this, according to articles like this Scope in js
thus, you usually will need to use
var that = this;