Access Modifiers
It is a convention in JavaScript that a class member whose name starting with an underscore is "private", that is, it is intended for internal use and should not be considered part of the public API of the class. However, one can in fact define a de facto private members using closures. In the following example,new MyClass will return an object with only the properties assigned to this object and in the prototype object of the class.var MyClass = (function () {
// private static field
var counter = 0;
// constructor
var ctor = function (_name) {
// private instance field
var _id = ++counter;
// public instance method
// Private instance members can only be accessed this way
this.getName = function () { return _name }; // readonly
this.getID = function () { return _id }; // readonly
};
// public instance method (shared across instances)
// Note that class methods cannot access instance members.
ctor.prototype.toString = function () {
return 'Hi! My my name is ' + this.getName()
+ ', my id is ' + this.getID()
+ ' and there are ' + counter + ' instances in total.'
};
// public static method
ctor.getNumInstances = function () { return counter };
return ctor;
})();
// Error: cannot access id outside ctor
MyClass.prototype.setID = function(id){ this.id = id; }
Inheritance
Javascript doesn't exactly have subclass objects, but prototype is a useful workaround to make a "base class" object of certain functions that act as objects. For example:/* Definition of class Person */
var Person = function(name) {
this.name = name;
this.canTalk = true;
this.greet = function() {
if (this.canTalk) console.log("Hi, I'm " + this.name);
};
};
/* Definition of subclass Employee */
var Employee = (function() {
var ctor = function(name, title) {
// call parent constructor
Person.call(this, name);
// initializations for Emplyee
this.title = title;
};
// store the method before overriding it
var _greet = ctor.greet || Person.prototype.greet;
// overriding parent's method
ctor.prototype.greet = function() {
// call the original method
_greet.apply(this, arguments);
console.log("I'm a " + this.title);
};
// setup the prototype chain
ctor.prototype = Object.create(Person.prototype);
ctor.prototype.constructor = ctor; // repair the inherited constructor
return ctor;
})();
References and Resources
1. Introduction to Object-Oriented JavaScript2. Prototypes Are Not Classes
3. Constructors in JavaScript objects
4. Douglas Crockford: Advanced JavaScript (Video)
5. Constructors Considered Mildly Confusing
6 JavaScript The Definitive Guide, 6th Edition, Chapter 9
(http://js-bits.blogspot.com.au/2010/08/javascript-inheritance-done-right.html)
No comments:
Post a Comment