0

I'm trying to understand JavaScript scope better, and am not sure why something isn't working.

I've defined an object like this:

var my_obj =
{
    foo:function()
    {
        this.bar()
    },
    bar:function()
    {
        console.log('hello world!');
    }
}
my_obj.foo();

But I get the error "TypeError: this.bar is not a function" and I don't understand why.

I am also trying to use another piece of code I wrote earlier from within this new block and that isn't working properly either. Here the following happens:

var my_obj =
{
    foo:function()
    {
        feedback('hello world!');
    }
}
my_obj.foo();

feedback = function(msg,y)
{
     if( !y )
     {
         setTimeout(function()
         {
             feedback(msg,1);
         } , 1000 );
         return;
     }
     else
     {
         console.log(msg);
     }
}

This used to work fine (if I called feedback() from within the global scope), but now, feedback is called fine from foo, but then the timed out call to feedback fails unless I call window.feedback() from within setTimeout.

Any ideas on either of these issues?

Thanks

Update

Here is my code (which will give both errors): http://jsbin.com/ecotoj/12/edit

Thanks to Asad for showing me the issue that the context of 'this' was changed within $.ajax (and that you can use jQuery's context option within $.ajax to re-define it)

Matt McDonald
  • 4,791
  • 2
  • 34
  • 55
  • 5
    Worksforme. Are you sure you called `my_obj.foo();` - the [`this` keyword](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this) relies on that? – Bergi Oct 14 '12 at 20:01
  • Copy and paste: http://jsbin.com/irijiy/2/edit – J. Holmes Oct 14 '12 at 20:02
  • Your second example fails probably because you called `feedback` from foo before you assigned to it - check out http://stackoverflow.com/q/336859/1048572 – Bergi Oct 14 '12 at 20:05
  • No I called it like this: http://jsbin.com/ecotoj/1/edit where the attr would have been my_obj. Would this make a difference? – Matt McDonald Oct 14 '12 at 20:05
  • @mattm591: That jsbin example is incomplete. There is a syntax error, there is no `g` object, there is no element with that attribute, and there is no object with a foo method that is a property of `window`. – Bergi Oct 14 '12 at 20:14
  • In the second question, the if (!y) prevents subsequent calls after calling feedback(msg,1) - the "1" does not pass the !y test. – ron tornambe Oct 14 '12 at 20:22
  • OK, but I changed it to true and I still get the same error that feedback isn't of type function. – Matt McDonald Oct 15 '12 at 08:20
  • @Bergi: I've updated the jsbin at http://jsbin.com/ecotoj/12/edit – Matt McDonald Oct 15 '12 at 09:02
  • @mattm591: There's still no `$('*[data-module-load]')`, so nothing will is executed. However, I can see your mistake: the [`this` keyword](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this) in your success callback does not point to `my_obj`, but to the ajax object. You will have to save that reference in a variable; [directly] inside your `foo` method it points to what you want. – Bergi Oct 15 '12 at 14:06

1 Answers1

0

In the second question, you are calling feedback before it has been defined. Try calling my_obj.foo() after defining feedback. Additionally, make sure that all of this is occurring in the global scope (since you're trying to refer to the global object feedback)

Asad Saeeduddin
  • 46,193
  • 6
  • 90
  • 139
  • But my initial call to feedback from within foo() isn't the issue as this works fine. It's when I recall it from within the timeout I get an error. – Matt McDonald Oct 14 '12 at 20:12
  • it should be an issue, since at the time you are calling feedback no such method exists in any context right up to the window. if you had declared it using function feedback() etc. then it would have worked. As things stand I get an undefined exception on the first call. – Asad Saeeduddin Oct 14 '12 at 20:26
  • see [this](http://jsfiddle.net/dVjyr/4/show/light/) fiddle. Then uncomment the part I've labeled `//This fails` and watch the undefined exception get thrown. – Asad Saeeduddin Oct 14 '12 at 20:28
  • Sorry, I'm with you now. In my actual code the my_obj.foo() function is called when something is clicked (and all code is loaded). So in the example I should have put that line at the bottom. – Matt McDonald Oct 15 '12 at 08:17
  • In that case, this will still fail unless your feedback function is globally accessible. The function passed to setTimeout is executed with this being the window. – Asad Saeeduddin Oct 15 '12 at 08:20
  • But if feedback is defined outside of any other function/object/etc. then it is part of window isn't it? – Matt McDonald Oct 15 '12 at 08:22
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18039/discussion-between-asad-and-mattm591) – Asad Saeeduddin Oct 15 '12 at 08:22