1

I've been reading SO posts all day and I haven't come up with anything that is working for me.

I have a JS object

function MyObject(a,b){
     this.member_a = a;
     this.member_b = b;



     function operation1(){
          $('#someDiv1').text(this.a);
     }

     function operation2(){
          $('#someDiv1').text(this.b);
     }

     MyObject.prototype.PublicFunction1 = function(){

     //There is an ajax call here
     //success
     operation1();
     //failure
     operation2();

     }
}

Roughly like that. That's the pattern I'm at right now. It's in an external JS file. My page creates a MyObject(a,b) and the breakpoints show that member_a and member_b are both initialized correctly. After some other magic happens from my page callsMyObject.PublicFunction1();, the ajax executes and I enter operation1() or operation2() but when I am inside of those member_a and member_b are both undefined and I don't understand why. I'm losing the scope or something. I've had the private function and the prototypes outside the object body declaration, combinations of both. How can I call a private function from an object's prototype to work on the object's data?

I've also tried

ClassBody{
vars
private function
}

prototype{
private function call
}

and have been reading this

Bmo
  • 1,212
  • 11
  • 34
  • 1
    Assigning a function to the prototype inside the constructor is wrong. Please see [my answer here](http://stackoverflow.com/a/17393153/218196) to get an idea about what the prototype and the constructor are for. – Felix Kling Sep 24 '13 at 13:13
  • I've re-arranged my code to match. However when I enter the prototype function I have all the class variables, at the end of the ajax call they are all back to undefined and the only ones that are set are the ones returned from the call. It's like it re-inits at some point after the ajax is called. I don't get it. I might be thinking that a JS class = C# class and something is lost in translation. – Bmo Sep 24 '13 at 14:25

2 Answers2

1

operation1 and operation2 do not have a context and are thus executed in the global context (where this == window).

If you want to give them a context, but keep them private, then use apply:

operation1.apply(this);
operation2.apply(this);

Further reading on the apply method https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

EDIT

@FelixKing is correct - your code should more appropriately be written like this (using the Module Pattern):

//encapsulating scope
var MyObject = (function() {

     function operation1(){
          $('#someDiv1').text(this.a);
     }

     function operation2(){
          $('#someDiv1').text(this.b);
     }

     var MyObject = function(a,b) {
        this.member_a = a;
        this.member_b = b;
     };

     MyObject.prototype.PublicFunction1 = function(){

     //There is an ajax call here
     //success
     operation1.apply(this);
     //failure
     operation2.apply(this);

     }

     return MyObject;
}());
Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100
  • Thanks sir, I knew it was something to do with scope and context but I couldn't figure it out. Works like a champ. Acceptance in a few mins. Though I will say, i'm a bit sad since they are defined within the object's block that they would be able to assert/assume context that way. – Bmo Sep 24 '13 at 13:14
  • 2
    @Bmo: Assigning to the prototype inside the constructor is wrong! You will see the problem when you create more than one instance with the constructor. Maybe you are more after this solution: http://stackoverflow.com/q/55611/218196. – Felix Kling Sep 24 '13 at 13:16
  • I had them outside originally, but when I got into "Why won't it work?!" mode I got a bit loosey goosey with the placement. From http://www.phpied.com/3-ways-to-define-a-javascript-class/ see 1.2 – Bmo Sep 24 '13 at 13:20
0

I have built a tool to allow you to put private methods onto the prototype chain. This way you'll save on memory allocation when creating multiple instances. https://github.com/TremayneChrist/ProtectJS

Example:

var MyObject = (function () {

  // Create the object
  function MyObject() {}

  // Add methods to the prototype
  MyObject.prototype = {

    // This is our public method
    public: function () {
      console.log('PUBLIC method has been called');
    },

    // This is our private method, using (_)
    _private: function () {
      console.log('PRIVATE method has been called');
    }
  }

  return protect(MyObject);

})();

// Create an instance of the object
var mo = new MyObject();

// Call its methods
mo.public(); // Pass
mo._private(); // Fail
Trem
  • 100
  • 1
  • 3