命名空间与无冲突处理

  JS编程中我们可能会遇到命名冲突的问题。命名冲突分两种情况来处理,对于模块内部,我们通常创建命名空间来解决;对于不同框架类库,我们采用无冲突处理(多库共存)的手段解决。

1.模块内部,注册命名空间

  一个大模块可以细分成若干小模块,命名空间其实就是在大模块的作用域里面声明小的作用域,这样不同作用域之间同名标识符互不影响。

  1)用立即执行函数表达式(IIFE)作为作用域。

var a = 1;

(function() {
    var a = 2;
    console.log(a);//2
})();

console.log(a);//1

  IIFE内部想调用外部的同名变量,可以将外部同名变量当参数传进去,但是外部想调用IIFE作用域里的变量却不方便了。

  2)对象字面量方式创建命名空间。

  对象字面量{}括起来的就是一个作用域,我们通常声明一个对象字面量,然后用“.”的方式给它创建若干属性正是这种原理。

var Lxt = {
    A : {},
    B : {}
};
Lxt.A.a = 1;
Lxt.B.a = 2;
console.log(Lxt.A.a);//1
console.log(Lxt.B.a);//2

  A作用域里的a与B作用域里的a互不干扰,这就是对象字面量方式创建命名空间。

  3)使用注册函数创建命名空间。

  注册函数是上面那种方式的加强版,上面那个例子如果没事先定义A和B,则下面的Lxt.A.a会报错,注册函数其实就是将定义空间的过程封装了起来。

var Lxt = {};
var namespace = function(scope, space) {
    var spaces = space.split(".");
    var currentScope = scope;
    for(var i = 0, len = spaces.length; i < len; i++) {
        if(!currentScope[spaces[i]]) {
            currentScope[spaces[i]] = {};
        }
        currentScope = currentScope[spaces[i]];
    }
};

 namespace(Lxt, "A");
 namespace(Lxt, "B");

  得到的结果同2)中声明的Lxt一样。

2.不同类库无冲突处理

  无冲突处理的原理很简单,类库加载前保存冲突命名,类库加载后再将冲突命名重新赋值回去。

  拿“$”来举例,我在$1.js中声明一个全局变量“$”,在$2.js中也声明一个全局变量“$”,先加载$1,之后马上加载$2,调用时“$”则不会指向$1的$内容了。

//$1.js:
var $ = J = {
    test : function() {
        return "from $1.js...";
    }
};
//$2.js:
var $ = K = {
    test : function() {
        return "from $2.js...";
    }
};

  页面先后引入$1.js与$2.js后测试发现,访问不了$1的test函数了。

console.log($.test());//from $2.js...

  那么无冲突怎么处理呢?拿$2来举例,在$2代码最前面保存“$”,这时,变量保存了$1的内容,模仿JQuery的noConflict函数,调用该函数的时候将保存的变量重新赋给“$”。最终效果是“$”指向“$1”的内容。

//$2.js
var _$ = window.$;
var $ = K = {
    test : function() {
        return "from $2.js...";
    },
    noConflict : function() {
        window.$ = _$;
        return K;
    }
};

  测试结果如下:

$.noConflict();
console.log($.test());//from $1.js...

  

敌人总是会在你最不想它出现的地方出现!
原文地址:https://www.cnblogs.com/longhx/p/5452807.html