I am using John Resig's "Simple JavaScript Inheritance" to create a class that can be inherited. I am also using KnockoutJS for computed observables. The problem comes in trying to combine these two concepts. When I try to gain a reference to self in the computed observable I get the "Window" object instead of the expected actual object. Here is a quick code sample:
window.mynamespace.myclass = Class.extend({
init: function() {
},
someProperty: ko.observable(10),
someComputedProperty: ko.computed(function() {
return this.someProperty();
}, this)
});
Unforunately this.someProperty() is unable to be found because 'this' is a reference to Window. Any thoughts or ideas?
I've never had any experience with KnockoutJS. However I'm well versed with inheritance in JavaScript and I frown upon John Resig's "Simple JavaScript Inheritance" pattern (primarily because it doesn't have private variables). Instead I prefer using my own class pattern. I think you might find it interesting:
You may also use your method and simply skip creating
self
. Since the class is not created from an object you may usethis
within your class definition (something you can't do in John Resig's "Simple JavaScript Inheritance" pattern):You may also add methods directly to
window.mynamespace.myclass.prototype
. That way instead of returningself.someProperty()
you may returnmyclass.prototype.someProperty()
. Feel free to ask me if you need any help with my class pattern.Edit:
The
Class
constructor has two parameters: a function defining the class and an optional base class to derive from. The first argument (i.e. the function) must return another function which is the constructor of the class (similar to a C++ or Java constructor).Let's create a simple
Rectangle
class:Now you can create instances of the class
Rectangle
as demonstrated in this fiddle.Now let's do something more fun - inheritance. The second parameter of the
Class
constructor is the base class to derive from. Let's create a classSquare
which derives from the classRectangle
.This is where things get interesting. Okay so we have 4 types of data members in this class pattern:
private
,public
,shared
, andstatic
. We have already seen private and public data members.Shared data members are those properties defined on the
prototype
of a class. They are shared by all instances of the class.Static data members are those properties defined on the class itself. They are not inherited by the instances of the class.
In the above example when
Square
derives fromRectangle
it inherits all the shared and static data members ofRectangle
. In fact we may also define a new shared or static data member onRectangle
afterSquare
is defined and it will still be inherited bySquare
. Let's demonstrate this concept using an example:The above is for static data members. Let's see the same for shared data members:
You may see the output of the above program in the following fiddle.
That's cool, but what about private and public data members? How are they inherited? Well, private and public data members are not inherited when we create a new class. They are inherited when create a new instance of a class. This is because different instances of the same class have different private and public data members.
When we create an instance of a derived class (like
Square
) we don't inherit the private and public data members of it's base class (i.e.Rectangle
) until we call the base class constructor (i.e.uber
). Only when we call the base class constructor are the private and public data members inherited (actually only the public data members are inherited - the others are called private for a reason):You may see the output of the above program in the following fiddle.
Now let's create another class for kicks, and while we're at it we'll also demonstrate multilevel inheritance:
This is something new. Here we created a new
area
function which shadowed thearea
function defined inRectangle
, but what if we wanted to access the base class methods from the derived class?Well, when we call the base class constructor (i.e.
uber
) it returns the instance of the base class. Since we don't need the base class constructor anymore we save the instance asuber
. Then we may call the base classarea
method usinguber.area
as seen in thearea
andvolume
functions.You may see the output of the above program in the following fiddle.
Thus you may see that this class pattern is much more powerful than John Resig's "Simple JavaScript Inheritance" pattern, and the
Class
constructor is only 47 lines of code (without being minified).You could always add them in the
init
. In knockout's own examples they do their binding in the constructor.Or capturing a reference to
this
and forgetting about binding:Edit:
To demonstrate how you'd extend the class: