Why Is "This" in an Anonymous Function Undefined When Using Strict

Why is this in an anonymous function undefined when using strict?

It's because, until ECMAscript 262 edition 5, there was a big confusion if people who where using the constructor pattern, forgot to use the new keyword. If you forgot to use new when calling a constructor function in ES3, this referenced the global object (window in a browser) and you would clobber the global object with variables.

That was terrible behavior and so people at ECMA decided, just to set this to undefined.

Example:

function myConstructor() {
this.a = 'foo';
this.b = 'bar';
}

myInstance = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance = myConstructor(); // oh my gosh, we just created a, and b on the window object

The last line would throw an error in ES5 strict

"TypeError: this is undefined"

(which is a much better behavior)

If a strict mode function is executed using function invocation, its 'this' value will be undefined

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.org/en-US/docs/Web/API/Event/target


Click Me

Fiddle with the code:

https://jsfiddle.net/24epdxbz/2

From yehudakatz:

The ECMAScript 5 spec says that undefined is (almost) always passed, but that the function being called should change its thisValue to the global object when not in strict mode. This allows strict mode callers to avoid breaking existing non-strict-mode libraries.

Why does 'this' return 'undefined' when referred in an arrow function but doesn't when called on an anonymous function?

Because arrow functions don't have their own this, they close over the this of the calling context. But non-arrow functions, if they're not bound, take this based on how they're called. I assume you're calling these functions like this:

obj.getScopeWithArrow();
obj.getScopeWithAnonymous();

In the first case, again, the arrow function doesn't get its own this so it doesn't matter how you're calling it. In the second case, it does matter, and calling it like that makes this within the call refer to the same object obj refers to.


Separately: In your example, you must be in strict mode, because this can only be undefined in strict mode.

Separately 2: With regard to your method names: this and "scope" have very, very little to do with one another.


Some examples:

function showThis(label, t) {  if (t === window) {    console.log(label, "(global object)");  } else {    console.log(label, t);  }}// Loose mode by default in a non-module script elementlet obj = {  arrow: () => {    showThis("arrow says ", this);  },  normal: function() {    showThis("normal says ", this);  }};obj.arrow();  // global object (window on browsers)obj.normal(); // obj
function foo() { // Here, we're in strict mode "use strict"; let obj = { arrow: () => { showThis("arrow says ", this); }, normal: function() { showThis("normal says ", this); } }; obj.arrow(); // undefined obj.normal(); // obj
}foo();

Why is this undefined in a function defined and called in a JS class method. I exepected this to be window

1)function(){} declaration defines its own 'this' reference to context. In 'strict mode' such context will be undefined by default, in non-strict mode it will be 'window'

2) Class declarations evaluated in strict mode by standart https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Strict_mode

JavaScript undefined variable in an anonymous function

Closure issue.

Try adding a 3rd parameter to the setTimeout (doesn't work):

setTimeout(function(i){
children[i].style.display = "block";
console.log(i);
}, 2000, i);

Example

Another formate:

    var i = 0;
var timer = setInterval(function () {
children[i].style.display = "block";
i++;
if (i == children.length) {
clearInterval(timer);
}
}, 2000);

EXAMPLE

ES6 is around the corner, the let statement is especially built for situations like this:

for (let i = 0; children.length > i; i++ ) {
setTimeout(function(){
children[i].style.display = "block";
console.log(i);
}, 2000);
}

However this is not the answer you need for right now. This was just a note.

Using undefined in self-executing anonymous function

I wanted to also protect 'undefined' from being redefined

and

There's a compilation error due to the strict mode: "Certain variables such as undefined are no longer writeable"

So what is your problem? There is no need to declare a undefined argument, because CoffeeScript won't let you use this "variable" anyway!

If you really (need/want to) worry about some third party script assigning a value to undefined, don't use it in your code. You can always use the typeof operator or CoffeeScripts existential operator instead.

Just don't worry about it. I think no one ever encountered such an error, apart from explicitly malicious attacks.

this inside an anonymous function?

Is this code from the book? I have the book, but I haven't read through it.

It's an error in the book. Check the errata: http://www.apress.com/9781590597279

Inside the anonymous function, this is the global window.

You could make it work by adding .call(this, i) after it.

function User(properties) {
// Iterate through the properties of the object, and make sure
// that it's properly scoped (as discussed previously)
for (var i in properties) {
(function(i) {
// Create a new getter for the property
this["get" + i] = function() {
return properties[i];
};
// Create a new setter for the property
this["set" + i] = function(val) {
properties[i] = val;
};
}).call(this, i);
}
}

javascript object undefined under anonymous function

Your code is incorrectly assuming that this will refer to a "ConstructNodes" object inside the event handlers. It won't; it'll be the element. Instead, store this in an object, and things will be better:

ConstructNodes.prototype.getId = function(){
var nodes = document.getElementsByClassName(this.className), obj = this;
for (var i=0;i<nodes.length;i++){
nodes[i].onclick = function(){
var r = confirm(obj.alertMsg);
if (r==true){
alert(obj.hiddenId); // undefined
document.getElementById(obj.hiddenId).value = this.id;
alert(obj.hiddenId);
} else {
return;
}
};
}
};

(It's not at all clear what you're trying to do, so there may be some issues still.)



Related Topics



Leave a reply



Submit