JavaScript 简易继承实现

来源:互联网 发布:js 浏览 后退不刷新 编辑:程序博客网 时间:2024/05/06 21:02

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

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:ClassDClassB.log:ClassDClassA.log:ClassD测试二:ClassC.log:张三ClassB.log:张三ClassA.log:张三classE.print:张三/100

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

0 0