javascript Dean Edwards的Base.js实现对象继承

原文地址:http://dean.edwards.name/weblog/2006/03/base/

 

A Base Class for JavaScript Inheritance

NB. I’ve amended the code samples below to reflect recent changes in this class.

I’m anOOprogrammer at heart and JavaScript supports prototype based inheritance. Unfortunatley this leads to verbose class definitions:

function Animal(name) {};
Animal.prototype.eat = function() {};
Animal.prototype.say = function(message) {};

I want a nice base class for JavaScriptOO:

  • I want to easily create classes without theMyClass.prototypecruft
  • I want method overriding with intuitive access to the overridden method (like Java’ssuper)
  • I want to avoid calling a class’ constructor function during the prototyping phase
  • I want to easily add static (class) properties and methods
  • I want to achieve the above without resorting to global functions to build prototype chains
  • I want to achieve the above without affectingObject.prototype

The Base Class

I’ve created a JavaScript class (Base.js) that I hope eases the pain of JavaScriptOO. It’s a simple class and extends theObjectobject by adding two instance methods and one class method.

TheBaseclass defines two instance methods:

extend

Call this method to extend an object with another interface:

var object = new Base;
object.extend({
	value: "some data",
	method: function() {
		alert("Hello World!");
	}
});
object.method();
// ==> Hello World!
base

If a method has been overridden then thebasemethod provides access to the overridden method:

var object = new Base;
object.method = function() {
	alert("Hello World!");
};
object.extend({
	method: function() {
		// call the "super" method
		this.base();
		// add some code
		alert("Hello again!");
	}
});
object.method();
// ==> Hello World!
// ==> Hello again!

You can also call thebasemethod from within a constructor function.

Creating Classes

Classes are created by calling theextendmethod on theBaseclass:

var Animal = Base.extend({
	constructor: function(name) {
		this.name = name;
	},
	
	name: "",
	
	eat: function() {
		this.say("Yum!");
	},
	
	say: function(message) {
		alert(this.name + ": " + message);
	}
});

All classes created in this manner will inherit theextendmethod so we can easily subclass theAnimalclass:

var Cat = Animal.extend({
	eat: function(food) {
		if (food instanceof Mouse) this.base();
		else this.say("Yuk! I only eat mice.");
	}
});
	
var Mouse = Animal.extend();

Class Properties and Methods

A second parameter passed to theextendmethod of a class defines the class interface:

var Circle = Shape.extend({ // instance interface
	constructor: function(x, y, radius) {
		this.base(x, y);
		this.radius = radius;
	},
	
	radius: 0,
	
	getCircumference: function() {
		return 2 * Circle.PI * this.radius;
	}
}, { // class interface
	PI: 3.14
});

Note the use of thebasemethod in the constructor. This ensures that theShapeconstructor is also called. Some other things to note:

  • If you define a class method (not an instance method) calledinitit will be automatically called when the class is created
  • Constructor functions are never called during the prototyping phase (subclassing)

Classes With Private Data

Some developers prefer to create classes where methods access private data:

function Circle(radius) {
	this.getCircumference = function() {
		return 2 * Math.PI * radius;
	};
};

You can achieve the same result using the Base class:

var Circle = Shape.extend({
	constructor: function(radius) {
		this.extend({
			getCircumference: function() {
				return 2 * Math.PI * radius;
			}
		});
	}
});

The code is slightly more verbose in this case but you get access to thebasemethod which I find incredibly useful.

Single Instances

I changed my mind a lot about this but finally decided to allow the creation of single instance classes by defining anullconstructor:

var Math = Base.extend({
	constructor: null,
	PI: 3.14,
	sqr: function(number) {
		return number * number;
	}
});

Conclusion

This supersedes my oldOOframework which was not as cross-browser as I would have liked (and had other shortcomings).

I have a development area where I’m developing bits and pieces based on this engine. Most of this is work in progress but illustrates the flexibility of this technique.

You can grab theBaseclass here: Base.js.

 

你可能感兴趣的:(javascript Dean Edwards的Base.js实现对象继承)