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