0

Why do I get the following error in the google dev console when loading the script from a web page?

But if I step through the code with the dev tool debugger the error does not occur and this.name = 'Jane Doe' as expected?

index.html

<script type="text/javascript" src="main.js"></script>

main.js

'use strict';
var name = 'Jane Doe',
    greet = function () {
        return 'My name is ' + this.name;
    };
console.log(greet());

console:

Uncaught TypeError: Cannot read property 'name' of undefined

2 Answers2

4

this is not bound to the global object in strict mode.

The value of this is not converted to the global object when it is null or undefined. JavaScript

function testFunc() {
    return this;
}
var testvar = testFunc();

In non-strict mode, the value of testvar is the global object, but in strict mode the value is undefined.

http://msdn.microsoft.com/en-us/library/br230269(v=vs.94).aspx

That solves most of it. I still can't explain why it works while stepping through the code in the chrome debugger.

CDspace
  • 2,551
  • 17
  • 31
  • 35
0

Because you're kind of abusing the global namespace here, which is bad. this is usually assigned to window when there's no other scope. But if that function was handling, say a DOM event, then this would be the element that fired the event. So long story short, you should usually not rely on this to be set to something.

Either set it explicitly using call or apply, as very nicely explained here: What is the difference between call and apply?.

Or save a particular this and define your function as a closure around it:

self = window;
self.name = 'Jane Doe';
self.greet = function () {
    return 'My name is ' + self.name;
};
console.log(self.greet());

That code makes me feel dirty though. Only clobber the global namespace like that if you Absolutely must. Like, for example, when you're defining the jQuery variable, or the ko variable (with knockout). And even then, don't do it like this :)

Of course this is totally fine to use, but you should really understand it properly before using it. And that goes beyond the scope of this question.

Community
  • 1
  • 1
Milimetric
  • 13,020
  • 4
  • 40
  • 53
  • "*`this` is usually assigned to `window` when there's no other scope.*" - yes, exactly, that's what the OP stated. But his question is: Why is it not in his case? – Bergi Jan 30 '14 at 04:51
  • As I say after, their function must be invoked some other way. I mean, there's no magic here, and if there's an example of this failing, I'd like to see it. I pasted it in a jsfiddle and it works as expected. – Milimetric Jan 30 '14 at 14:46
  • 1. So it seems to be the consensus that this != the global namespace when in strict mode. 2. It seems strange that the google debugger allows it to work when stepping through the code. – user3251454 Jan 30 '14 at 21:25
  • 1
    Maybe the google debugger is using eval so it can't be in strict mode. – Milimetric Jan 31 '14 at 01:00