代码改变世界

JavaScript继承(转载)

2010-03-19 10:21  爱研究源码的javaer  阅读(191)  评论(0编辑  收藏  举报
代码

var initializing = false;

function jClass(baseClass, prop) { 

   
//只接受一个参数的情况- jClass(prop)

    
if (typeof (baseClass) === "object") {

        prop 
= baseClass;

        baseClass 
= null;
    }

 
//本次调用所创建的类(构造函数)
    function F() {

//如果当前处于实例化类的阶段,则调用init原型函数
        if (!initializing) {

            
//如果父类存在,则实例对象的baseprototype指向父类的原型
            //这就提供了在实例对象中调用父类方法的途径
            if (baseClass) {

                
this.baseprototype = baseClass.prototype;
            }

            
this.init.apply(this, arguments);
        }
    }

   
//如果此类需要从其他类扩展
    if (baseClass) {

        initializing 
= true;

        F.prototype 
= new baseClass();

        F.prototype.constructor 
= F;

        initializing 
= false;
    }
    
//覆盖父类的同名函数
    for (var name in prop) {

//如果此类继承自父类baseClass并且父类原型中存在同名函数name
        if (prop.hasOwnProperty(name)) {


            
if (baseClass && typeof (prop[name]) === "function" && typeof (F.prototype[name]) === "function") {

                
//重定义函数name
                //首先在函数上下文设置this.base 指向父类原型中的同名函数
                //然后调用函数prop[name],返回函数结果

                
//注意:这里的自执行函数创建了一个上下文,这个上下文返回另一个函数,
                //此函数中可以应用此上下文中的变量,这就是闭包(Closure)
            //这是Javascript框架开发中的常用技巧
               
                F.prototype[name] 
= (function(name, fn) { return function() { this.base = baseClass.prototype[name]; return fn.apply(this, arguments); } })(name, prop[name]);

            }
            
else {

                F.prototype[name] 
= prop[name];
            
            }
        
        }
    }

    
return F;
}

var Person = jClass({

    init: 
function(name) {
        
this.name = name;
    },
    getName: 
function() {
        
return this.name;
    }
});

var Employee = jClass(Person, {

    init: 
function(name, employeeID) {
        
this.base(name);

        
this.employeeID = employeeID;
    },

    getEmployeeID: 
function() {
        
return this.employeeID;
    },

    getName: 
function() {
        
return "Employee name:" + this.base();
    }

});

var zhang = new Employee("ZhangSan""1234"); //调用原型的init函数,再调用覆盖的init函数,再执行this.base函数再执行基类的init函数

alert(zhang.getName());
//调用原型的getName()函数,再调用覆盖的getName函数,再调用base()函数,再执行基类的getName函数

转自:http://www.cnblogs.com/sanshi/archive/2009/07/13/1522647.html