Encapsulation in javascript

I need to create a simple reusable javascript object that publishes multiple methods and a parameterized constructor. After reading a few tutorials on OOP in JavaScript, I am sitting here with an empty head. How on earth can I do this?

Here is my last non-working code:

SomeClass = function(id) {
    this._id = id;
}
(function() {
    function intFun() {
        return this._id;
    }
    SomeClass.prototype.extFun = function() {
        return incFun();
    }
})();

      

+1


source to share


4 answers


All vars are private:

SomeClass = function (id) {
    var THIS = this; // unambiguous reference
    THIS._id = id;

    var intFun = function () { // private
        return THIS._id;
    }

    this.extFun = function () { // public
        return intFun();
    }
}

      



Use in private methods as it will not be what you expected. THIS

THIS

+1


source


This is my usual approach:

MyClass = function(x, y, z) {
   // This is the constructor. When you use it with "new MyClass(),"
   // then "this" refers to the new object being constructed. So you can
   // assign member variables to it.
   this.x = x;
   ...
};
MyClass.prototype = {
    doSomething: function() {
        // Here we can use the member variable that
        // we created in the constructor.
        return this.x;
    },
    somethingElse: function(a) {
    }
};

var myObj = new MyClass(1,2,3);
alert(myObj.doSomething()); // this will return the object "x" member
alert(myObj.x); // this will do the same, by accessing the member directly

      

Usually the keyword "this", when used in one of the methods of an object, refers to the object itself. When you use it in the constructor, it will refer to the new object being created. Thus, in the above example, both warning statements will display "1".


The exception to this rule is when you pass one of your member functions elsewhere and then call it. For example,



myDiv.onclick = myObj.doSomething;

      

In this case, JavaScript ignores the fact that "doSomething" belongs to "myObj". As a result, "this" inside doSomething will point to another object, so the method will not work as expected. To work around this, you need to specify the object that "this" should refer to. You can do this with a JavaScript "call" function:

myDiv.onclick = function() {
    myObj.doSomething.call(myObj);
}

      

It's weird, but eventually you get used to it. The bottom line is that when traversing methods, you also need to walk around the object on which they should be called.

+5


source


I'm usually not too worried about hiding the internals, although I prefix them with underscores to mark them as not intended for use outside of the "class". Usually I will do:

var MyClass = function() {};

MyClass.prototype = {
   _someVar : null,
   _otherVar : null,

   initialize: function( optionHash ) {
                _someVar = optionsHash["varValue"];
                _otherVar = optionsHash["otherValue"];
           },

   method: function( arg ) {
               return _someVar  + arg;  
           },
};

      

And use it like this ...

var myClass = new MyClass( { varValue: -1, otherValue: 10 } );
var foo = myClass.method(6);

      

+3


source


From http://learn.jquery.com/code-organization/concepts/#the-module-pattern :

// The module pattern
var feature = (function() {

    // private variables and functions
    var privateThing = "secret";
    var publicThing = "not secret";

    var changePrivateThing = function() {
        privateThing = "super secret";
    };

    var sayPrivateThing = function() {
        console.log( privateThing );
        changePrivateThing();
    };

    // public API
    return {
        publicThing: publicThing,
        sayPrivateThing: sayPrivateThing
    };

})();

feature.publicThing; // "not secret"

// logs "secret" and changes the value of privateThing
feature.sayPrivateThing();

      

Thus, using a return object that pseudo-dumps its "methods" might be another way to do it.

I read from http://www.amazon.com/Programming-Oracle-Press-Poornachandra-Sarang-ebook/dp/B0079GI6CW that it's always good to use getters and setters rather than accessing the variable directly from outside the object to eliminate the need to return variables by reference.


By the way, you can just use this.variable

to reference / declare a public variable and var variable

to declare a private variable.


I know this is a late answer, but I hope it helps anyone reading it in the future.

+1


source







All Articles