javascript 继承、命名空间实现分享

命名空间是用来组织和重用代码的编译单元,在大型项目开发中javascript使用的越来越多时,我们就应该将项目里的js类库管理起来,如何将自己进行归类管理,防止命名冲突,但是Javascript默认不提供这样的功能,看了这篇文章你就能解决这些问题了。

先说一下javascript命名空间的实现吧,直接上代码:

var Company = window.Company  || {};
Company.namespace = function (ns) {
    if (!ns || !ns.length) {
        return null;
    }
    var levels = ns.split(".");
    var nsobj = Company ;
    //如果申请的命名空间是在Company下的,则必须忽略它,否则就成了Company.Company 了
    for (var i = (levels[0] == "Company") ? 1 : 0; i < levels.length; ++i) {
        //如果当前命名空间下不存在,则新建一个关联数组。
        nsobj[levels[i]] = nsobj[levels[i]] || {};
        nsobj = nsobj[levels[i]];
    }
    //返回所申请命名空间的一个引用;
    return nsobj;
};

使用方法:

Company.namespace("Company.AbcClass");

/// <summary>
/// XXXXX
/// </summary>
Company.AbcClass = function () {
   
};
/// <summary>
/// XXXXX
/// </summary>
HySoft.FormDesign.prototype = {
    abc:"",
   abcFunction: function(){
   }       
};

Javascript继承实现

(function () {
    // 当前是否处于创建类的阶段
    var initializing = false;
    jsClass = function () { };
    jsClass.extend = function (prop) {
        // 如果调用当前函数的对象(这里是函数)不是Class,则是父类
        var baseClass = null;
        if (this !== jsClass) {
            baseClass = this;
        }
        // 本次调用所创建的类(构造函数)
        function F() {
            // 如果当前处于实例化类的阶段,则调用init原型函数
            if (!initializing) {
                // 如果父类存在,则实例对象的baseprototype指向父类的原型
                // 这就提供了在实例对象中调用父类方法的途径
                if (baseClass) {
                    this._superprototype = baseClass.prototype;
                }
                this.Init.apply(this, arguments);
            }
        }
        // 如果此类需要从其它类扩展
        if (baseClass) {
            initializing = true;
            F.prototype = new baseClass();
            F.prototype.constructor = F;
            initializing = false;
        }
        // 新创建的类自动附加extend函数
        F.extend = arguments.callee;

        // 覆盖父类的同名函数
        for (var name in prop) {
            if (prop.hasOwnProperty(name)) {
                // 如果此类继承自父类baseClass并且父类原型中存在同名函数name
                if (baseClass &&
                        typeof (prop[name]) === "function" &&
                        typeof (F.prototype[name]) === "function" &&
                        /\b_super\b/.test(prop[name])) {
                    // 重定义函数name - 
                    // 首先在函数上下文设置this._super指向父类原型中的同名函数
                    // 然后调用函数prop[name],返回函数结果
                    // 注意:这里的自执行函数创建了一个上下文,这个上下文返回另一个函数,
                    // 此函数中可以应用此上下文中的变量,这就是闭包(Closure)。
                    // 这是JavaScript框架开发中常用的技巧。
                    F.prototype[name] = (function (name, fn) {
                        return function () {
                            this._super = baseClass.prototype[name];
                            return fn.apply(this, arguments);
                        };
                    })(name, prop[name]);
                } else {
                    F.prototype[name] = prop[name];
                }
            }
        }
        return F;
    };
})();

使用方法:

var jsBasePage = jsClass.extend({
    Init: function() {
        debugger;
    },
    Load: function() {
        debugger;
    },
    PreRender: function() {

    },
    Ajax: function() {
        debugger;
    }
});

var ABC = jsBasePage.extend({
    Load: function() {
        debugger;
        this._super();
    }
});

var abc = new ABC();

abc.Load();

代码比较简单,就不做解释了,实现原理和部分代码也是从网上借鉴的(原始地址已经找不到了)。