1
var Test = (function() {
    return {
        useSub: function () {
            this.Sub.sayHi();
        },

        init: function () {
            $(document).ready(this.useSub);
        }
    };
})();

Test.Sub = (function () {
    return {
        sayHi: function () {
            alert('hi');
        }
    };
})();

Test.useSub(); // works
Test.init(); // explodes

Above I am trying to create a Test namespace and add an object Sub to it. I was doing fine until I tried using the object in jQuery. The error is "Uncaught TypeError: Cannot call method 'sayHi' of undefined". If there is a better way to do this, I am open to it.

Edit:

Obviously this was demo code. In my real application the solution that I went with because I think it is the most clear is this one:

var Namespace (function () {
  return {
    init: function () {
      $(document).ready(function() {
        Namespace.onReady();
      }
    },
    onReady: function() {
      alert('Now I am back in the Namespace scope. Proceed as planned');
    }
  };
})();

Edit2: All jQuery callbacks seem to require they are used in this manner or else the scoping is screwed up.

3 Answers 3

5

I think it is a scope problem. If you do

$(document).ready(this.useSub);

then this.useSub will be executed in the window scope (so inside the function, this refers to the window object) and there doesn't exist a Sub attribute.

Try:

init: function () {
    var obj = this;
    $(function(){obj.useSub()});
}

For some reason it does not work using $(document).ready(function(){obj.useSub()}); but it works with the $() shortcut.

Sign up to request clarification or add additional context in comments.

2 Comments

var that = this; $(document).ready(function () {that.useSub();}); Works for me.
@Skilldrick: I tested it with JS Bin and it does not work there, but then it has probably to do with their setup.
2

Here is one way

var Test = {
  useSub : function () { 
    Test.Sub.sayHi(); 
  }, 
  init: function () { 
    $(document).ready(Test.useSub); 
  },
  Sub: {
    sayHi: function () { 
      alert('hi'); 
    } 
  }
};

Comments

1

in this line:

$(document).ready(this.useSub);

you're passing a reference to a function and the scope is lost- when the function runs, this no longer means Test.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.