日期:2014-05-16  浏览次数:20332 次

我对js类继承的尝试
/**
 *
 * 用于类继承
 * User: yxx
 * Date: 10-4-14
 * Time: 上午11:01
 */
var Class = function (window) {
    function apply(o, c) {
        if (o && c && typeof c == 'object') {
            for (var p in c) {
                o[p] = c[p];
            }
        }
        return o;
    }
    /**
     *顶层基类
     */
    function Base() {
    }

    Base.superClass = Object;
    Base.prototype.is = function (type) {
        return this instanceof type;
    };

    /**
     * 在构造函数中使用,类似java语法中的super
     * 如果父类中也调用了Super则递归下去只到Base
     * 调用Super等this.constructor.superClass.apply(this, arguments);
     * ps:由于super是关键字所以首字母大写
     * @param args
     */
    Base.prototype.Super = function (args) {
        this.__super__ = (this.__super__ || this.constructor).superClass;//取得父类构造函数
        this.__super__.apply(this, arguments);//执行父类构造函数
        delete this.__super__;
    };

    /**
     * 继承一个类
     * @param supClass  父类
     * @param instances 实例方法和属性
     * @param statics 静态方法和属性
     */
    function extend(supClass, instances, statics) {
        if (typeof supClass != "function") {
            statics = instances;
            instances = supClass;
            supClass = Base;
        } else if (supClass == Object) {
            supClass = Base;
        } else if (!supClass.superClass) {
            supClass.extend(Base, supClass.prototype);
        } else {
            delete this.extend;
        }
        var spp = supClass.prototype;

        function PC() {//子类原型构造函数(prototype constructor)
        }

        PC.prototype = spp;//从父类继承实例方法和属性
        this.prototype = new PC();// 连接原型链完成继承
        apply(this.prototype, instances);// 绑定实例方法和属性
        apply(this, statics);// 绑定静态方法和属性
        this.superClass = supClass;// 父类
        this.prototype.superClass = spp;// 父类(原形)
        this.prototype.constructor = this;
    }


    function create(supClass, instances, statics) {
        var C = instances && instances.constructor;// 构造函数
        if (C == Object || typeof C != "function") {
            C = function Constructor() {
            };
        } else if (typeof instances == "function") {
            C = instances;
        }

        C.extend = extend;//为了不污染基础类没有把该方法直接绑定到Function.prototype上
        C.extend(supClass, instances, statics);
        return C;
    }

    return {
        create:create,
        extend:function(supClass,subClass, instances, statics){
            extend.call(subClass,supClass,instances,statics);
        }
    }
}(window);

//1.直接创建一个类默认继承Base
var Person = Class.create({constructor:function (name, age){
	this.name = name;
	this.age = age;
}});
//2.创建一个类并继承Pesson.
var User = Class.create(Person,function (name, age,sex){
	this.Super(name, age);
	this.sex = sex;
});

//3.构造函数,
function Teacher(name, age,sex){
      this.Super(name, age);
      this.sex = sex;
}
//继承Pesson
Class.extend(Person,Teacher);

//3.直接创建一个类默认继承Base
var Stu = Class.create({
      constructor:function (name, age,sex,no){
	 this.Super(name, age,sex);
	 this.no = no;
      },
      getAge:function(){
         return this.age;
      }
});

//更改父类为User.只有默认继承的父类为Base时才可以更改父类且只能改一次
Stu.extend(User);


//test
var p = new Person("张三",20);
var u = new User("李四",40,"女");
var s = new Stu("凤姐",70,男","10001");
alert(p.name);
alert(u.name);
alert(s.name);
alert(s.getAge());
alert(s.superClass.age);//访问被覆盖的父类属性或方法

alert(p instanceof Person);
alert(u instanceof Person);
alert(s instanceof Person);
alert(s instanceof User);

有什么意见好的想法大家一起改进