JavaScript 简易继承实现

最近发现写代码的效率超来超低了,花了两天的功夫,才写出这么一个段,凑合看看吧。

var FUNCTION_MARK_SEPARATOR = "__";//特殊分隔符
Function.prototype.bindFunction = function () {
    var self = this;
    var params = [];
    params.push.apply(params, arguments);
    var thisArg = params[0];
    params = params.slice(1);
    return function () {
        var arr =[];
        arr.push.apply(arr,params);
        arr.push.apply(arr,arguments);
        if(thisArg)
        {
            self.apply(thisArg, arr);
        }else{
            self.apply(this,arr);
        }
    }
}
//基础对象执行者
function baseFunctionExcenter()
{
        var params = [];
            params.push.apply(params, arguments);
        var self = this;
        var n = params[0];
        var name = n;
        if (arguments.callee) {
            var caller = arguments.callee.caller;//func->bindFunction->baseFunctionExcenter
            if (caller && (caller = caller.caller) && caller.name == n) {
                caller = caller.caller;
                if (caller && caller.___baseFunctionName == n && caller.___currentFunctionName) {
                    name = caller.___currentFunctionName;
                } else {
                    name = n;
                }
            }
        }
        name = FUNCTION_MARK_SEPARATOR + name;
        var func = self[name];
        if (func) {
            func.apply(self, params.slice(1));
        }
}
function initClass(obj) {
    obj.super = function () {
        var superClass = arguments[0];
        if (!superClass) return;
        var base = null;
        if (arguments.length > 1) {
            var F = function () { };
            F.prototype = superClass.prototype;
            base = new F();
            var params = [];
            params.push.apply(params, arguments);
            superClass.apply(base, params.slice(1));
        } else {
            base = new superClass();
        }
        var superResetList = [];//需要重置的对象
        var include = {};       
        for (var n in base) {
            var obj = base[n];
            this.super[n] = obj;
            if ("super" == n) continue;
            //去掉没有必要继承的对象
            if (typeof (n) == "string" && n.length >= FUNCTION_MARK_SEPARATOR.length &&
                FUNCTION_MARK_SEPARATOR == n.substr(0, FUNCTION_MARK_SEPARATOR) &&
                (!obj.____baseFunctionName || !obj.____currentFunctionName)) continue;
            if (typeof (obj) != "function") {
                if (!this[n]) this[n] = obj;
                continue;
            } else {
                if (!this[n]) {
                    include[n]=false;
                    var baseName = obj.___baseFunctionName || n;
                    var name = n;
                    if(include[baseName]===undefined)
                    {
                        include[baseName] = this[baseName];
                    }
                    if(include[baseName])
                    {
                        name = FUNCTION_MARK_SEPARATOR + n;
                        obj.___currentFunctionName = FUNCTION_MARK_SEPARATOR + obj.___currentFunctionName
                    }else{
                        name = n;
                    }
                    this[name] = obj;                   
                } else {
                    include[n] = true;
                    var baseName = obj.___baseFunctionName || n;
                    var name = FUNCTION_MARK_SEPARATOR + n;
                    var func = obj.bindFunction(null);
                    func.___baseFunctionName = baseName;
                    func.___currentFunctionName = name;
                    this[name] = func;
                }
                if (n.substr(0, FUNCTION_MARK_SEPARATOR.length) != FUNCTION_MARK_SEPARATOR) {
                    superResetList.push(n);
                }
            }
        }

        for (var i = 0; i < superResetList.length; i++) {
            var n = superResetList[i];
            this.super[n] = baseFunctionExcenter.bindFunction(this,n);
        }
    }
}

还算是比较简单吧,下面看看怎么用:

function ClassA() {
    this.name = 'ClassA';
}
ClassA.prototype = {
    log : function () {
        console.log("ClassA.log:" + this.name);
    }
}
function ClassB() {
    initClass(this);
    this.super(ClassA);
    this.name = 'ClassB';
}
ClassB.prototype = {
    log : function () {
        console.log("ClassB.log:" + this.name);
        this.super.log();
    }
}
function ClassC() {
    initClass(this);
    this.super(ClassB);
    this.name = 'ClassC';
}
ClassC.prototype = {
    log : function () {
        console.log("ClassC.log:" + this.name);
        this.super.log();
    }
}
function ClassD() {
    initClass(this);
    this.super(ClassC);
    this.name = 'ClassD';
}
var classD = new ClassD();
console.log("测试一:")
classD.log();

function ClassE(name, value) {
    this.name = name;
    this.value = value;
}
ClassE.prototype = {
    print : function () {
        console.log("classE.print:" + this.name + "/" + this.value);
    }
}
function ClassF(name, value) {
    initClass(this);
    this.super(ClassE, name, value);
    this.super(ClassD);
}
var classF = new ClassF("张三", "100");
console.log("测试二:")
classF.log();
classF.print();

输出结果:

测试一:
ClassC.log:ClassD
ClassB.log:ClassD
ClassA.log:ClassD
测试二:
ClassC.log:张三
ClassB.log:张三
ClassA.log:张三
classE.print:张三/100

需要注意的有:
“__”:被当成私有对象处理,不会被继承
“___baseFunctionName”、“____currentFunctionName”被当成继承者信息存储属性,不能当其它使用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值