-1

As seen here How to access the correct `this` context inside a callback? I try to use self instead of this. It's a little bit a stupid question about JS but I would like some explanations and what should I do to get it right.

(function (global) {

    "use strict";
    var self = this;

    function onDeviceReady () {
        self.test = "123";
        loadMapsApi();
    }
    function loadMapsApi () {
        console.log(self.test);
    }
})(window);

And it's not working :) What am I doing wrong ? I am using this code inside Cordova btw.. the error is the following

Uncaught TypeError: Cannot set property 'test' of undefined
Community
  • 1
  • 1

2 Answers2

7

When using strict mode, the value of this in a normal function call is undefined. That is exactly what your situation is. Your function:

(function (global) {

    "use strict";
    var self = this;
    ...

})(window);

Is just a normal function call so this will be undefined. If not using strict mode, then this in a normal function call will be set to the global object. Otherwise, this gets set to a unique value only when the function is called some other way (with new, with .apply() or .call() or as in obj.method()).


The self work-around you are using is for situations where this already points at the desired object and you want to save that reference for later use in callbacks. Since that is not the case in your code and it is not clear what you are expecting to use this for in your code, then it is not clear to use what to recommend to fix your problem without further description of what object you are trying to reference.

If you just want to reference the global object, then you can just reference global.test in your code.

(function (global) {

    "use strict";

    function onDeviceReady () {
        global.test = "123";
        loadMapsApi();
    }
    function loadMapsApi () {
        console.log(global.test);
    }
})(window);

If you are expecting this to point to some other object, then you will have to explain what you're expecting it to point to and then we can offer you an idea how to reference that specific object.


DO NOT just remove "use strict"; to make things work. The fact that your code doesn't work properly when using strict mode means that your code is using a bad practice that strict mode is designed to protect against. Instead, you should continue to use strict mode and, instead, fix your code to stop using the bad practice and work properly with strict mode.


For future reference, if you want to learn how Javascript decides what to set this to inside a function call, you can read this answer: When you pass 'this' as an argument. That answer lists the five different ways that the value of this is determined.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

Just remove "use strict"; line:

(function (global) {
    var self = this;

    function onDeviceReady () {
        self.test = "123";
        loadMapsApi();
    }
    function loadMapsApi () {
        console.log(self.test);
    }
})(window);

Fiddle

PDKnight
  • 712
  • 6
  • 25
  • LOL! So easy .. ahah thanks ! :) I don't know why I forgot that one there – user2391356 Mar 28 '16 at 20:26
  • @user2391356 no prob! :) – PDKnight Mar 28 '16 at 20:28
  • @user2391356 - This is a bad recommendation and should NOT be done. It is good to use `"use strict"`. And, when removing it makes your code works that means your code is using bad practices that `strict` mode is protecting you from. The code should be fixed to work with `"use strict"` instead. – jfriend00 Mar 28 '16 at 20:31
  • @jfriend00 Did I tell him it's bad to use `"use strict";` line? I don't see any text like that :) Anyways, his code works w/o that line :) – PDKnight Mar 28 '16 at 20:33
  • No, but you recommended a fix by removing `"use strict";`. That's not the right fix. The right fix is to fix the code while still use `strict` mode. `strict` mode here is telling them that their code is using a bad practice. You are recommending that they just change the syntax to allow the bad practice. – jfriend00 Mar 28 '16 at 20:36
  • @jfriend00 did he tell us he wants `"use strict";`? Citing: `...and what should I do to get it right.` so I recommended to remove the line. That's all. One more time, his code works without that line, he doesn't use any "bad practice" as you said :) – PDKnight Mar 28 '16 at 20:42