1

I need to create simple reusable javascript object publishing several methods and parameterized constructor. After reading through several "OOP in JavaScript" guides I'm sitting here with an empty head. How on the Earth can I do this?

Here my last non-working code:

SomeClass = function(id) {
    this._id = id;
}
(function() {
    function intFun() {
        return this._id;
    }
    SomeClass.prototype.extFun = function() {
        return incFun();
    }
})();
2
  • Did you cut and paste this code? There are a couple of typos: "functin" on line 4, and I believe "return incFun();" should be return "intFun();" Commented Dec 1, 2008 at 2:17
  • No. It's simplified version. I think I've fixed all typos now... Commented Dec 1, 2008 at 2:27

4 Answers 4

5

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's "x" member
alert(myObj.x); // this will do the same, by accessing the member directly

Normally the "this" keyword, when used in one of the object's methods, will refer to the object itself. When you use it in the constructor, it will refer to the new object that's being created. So in the above example, both alert statements will display "1".


An exception to this rule is when you pass one of your member functions somewhere else, 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, the "this" inside doSomething will point to another object, so the method won't work as expected. To get around this, you need to specify the object to which "this" should refer. You can do so with JavaScript's "call" function:

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

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

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

5 Comments

This approach couldn't hide internals of the class.
JavaScript can't hide internals of the "class".
Yep, bun in can be archived using anonymous function. But I've lost in "this" pointers in example above.
By the way, in this example I call object MyClass class because of it's role.
Artem: You can hide the internals using a trick with closures, but I would get comfortable with the above approach first. I'm editing the post to clarify the use of "this."
3

I usually don't worry too much about hiding the internals, although I do prefix them with underscores to mark them as not intended to be used outside the "class". Normally what I will do is:

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 as so...

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

Comments

1

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 THIS within private methods since this won't equal what you might expect.

1 Comment

Prefer self over THIS myself.
1

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();

So using returning an object that aliases its "methods" could be another way to do it.

I've read from http://www.amazon.com/Programming-Oracle-Press-Poornachandra-Sarang-ebook/dp/B0079GI6CW that it is always good practice to use getters and setters rather that accessing the variable directly from outside the object, so that would eliminate the need of returning variables by reference.


BTW you could 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 who reads it in the future.

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.