一个javascript继承的基础类Base.js

一个javascript继承的基础类Base.js

官网:http://dean.edwards.name

http://dean.edwards.name/weblog/2006/03/base/

一个javascript继承的基础类
首先我是一个面向对象的程序员,并且javascript支持prototype 方式继承,例如:

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

我想要一个更漂亮的基类,来实现javascript的面相对象.

1.我想不用prototype并容易地创建类.
2.我想用一个方法重写父类方法,就像java支持的那样.
3.在原型阶段我想要避免调用一个类的构造函数函数.
4.我想在类上容易的创建静态方法或属性.
5.我想实现上述功能不用全局函数
6.我想实现上诉功能不影响Object.prototype

/* 
    Base.js, version 1.1a 
    Copyright 2006-2010, Dean Edwards 
    License: http://www.opensource.org/licenses/mit-license.php 
*/  
  
var Base = function() {  
    // dummy  
};  
  
Base.extend = function(_instance, _static) { // subclass  
    var extend = Base.prototype.extend;  
      
    // build the prototype  
    Base._prototyping = true;  
    var proto = new this;  
    extend.call(proto, _instance);  
  proto.base = function() {  
    // call this method from any other method to invoke that method's ancestor  
  };  
    delete Base._prototyping;  
      
    // create the wrapper for the constructor function  
    //var constructor = proto.constructor.valueOf(); //-dean  
    var constructor = proto.constructor;  
    var klass = proto.constructor = function() {  
        if (!Base._prototyping) {  
            if (this._constructing || this.constructor == klass) { // instantiation  
                this._constructing = true;  
                constructor.apply(this, arguments);  
                delete this._constructing;  
            } else if (arguments[0] != null) { // casting  
                return (arguments[0].extend || extend).call(arguments[0], proto);  
            }  
        }  
    };  
      
    // build the class interface  
    klass.ancestor = this;  
    klass.extend = this.extend;  
    klass.forEach = this.forEach;  
    klass.implement = this.implement;  
    klass.prototype = proto;  
    klass.toString = this.toString;  
    klass.valueOf = function(type) {  
        //return (type == "object") ? klass : constructor; //-dean  
        return (type == "object") ? klass : constructor.valueOf();  
    };  
    extend.call(klass, _static);  
    // class initialisation  
    if (typeof klass.init == "function") klass.init();  
    return klass;  
};  
  
Base.prototype = {      
    extend: function(source, value) {  
        if (arguments.length > 1) { // extending with a name/value pair  
            var ancestor = this[source];  
            if (ancestor && (typeof value == "function") && // overriding a method?  
                // the valueOf() comparison is to avoid circular references  
                (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&  
                /\bbase\b/.test(value)) {  
                // get the underlying method  
                var method = value.valueOf();  
                // override  
                value = function() {  
                    var previous = this.base || Base.prototype.base;  
                    this.base = ancestor;  
                    var returnValue = method.apply(this, arguments);  
                    this.base = previous;  
                    return returnValue;  
                };  
                // point to the underlying method  
                value.valueOf = function(type) {  
                    return (type == "object") ? value : method;  
                };  
                value.toString = Base.toString;  
            }  
            this[source] = value;  
        } else if (source) { // extending with an object literal  
            var extend = Base.prototype.extend;  
            // if this object has a customised extend method then use it  
            if (!Base._prototyping && typeof this != "function") {  
                extend = this.extend || extend;  
            }  
            var proto = {toSource: null};  
            // do the "toString" and other methods manually  
            var hidden = ["constructor", "toString", "valueOf"];  
            // if we are prototyping then include the constructor  
            var i = Base._prototyping ? 0 : 1;  
            while (key = hidden[i++]) {  
                if (source[key] != proto[key]) {  
                    extend.call(this, key, source[key]);  
  
                }  
            }  
            // copy each of the source object's properties to this object  
            for (var key in source) {  
                if (!proto[key]) extend.call(this, key, source[key]);  
            }  
        }  
        return this;  
    }  
};  
  
// initialise  
Base = Base.extend({  
    constructor: function() {  
        this.extend(arguments[0]);  
    }  
}, {  
    ancestor: Object,  
    version: "1.1",  
      
    forEach: function(object, block, context) {  
        for (var key in object) {  
            if (this.prototype[key] === undefined) {  
                block.call(context, object[key], key, object);  
            }  
        }  
    },  
          
    implement: function() {  
        for (var i = 0; i < arguments.length; i++) {  
            if (typeof arguments[i] == "function") {  
                // if it's a function, call it  
                arguments[i](this.prototype);  
            } else {  
                // add the interface using the extend method  
                this.prototype.extend(arguments[i]);  
            }  
        }  
        return this;  
    },  
      
    toString: function() {  
        return String(this.valueOf());  
    }  
});

 extend

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

 base

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!

Creating Classes

var Animal = Base.extend({  
    constructor: function(name) {  
        this.name = name;  
    },  
      
    name: "",  
      
    eat: function() {  
        this.say("Yum!");  
    },  
      
    say: function(message) {  
        alert(this.name + ": " + message);  
    }  
});  
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();


你可能感兴趣的:(一个javascript继承的基础类Base.js)