js避免命名冲突
[1]工程师甲编写功能A
- var a = 1;
- var b = 2;
- alert(a+b);//
[2]工程师乙添加新功能B
- var a = 2;
- var b = 1;
- alert(a-b);//
[3]上一步中,工程师乙在不知情的情况下,定义了同名变量a,产生冲突。于是使用匿名函数将脚本包起来,让变量作用域控制在匿名函数之内。
- //功能A
- (function(){
- var a = 1;
- var b = 2;
- alert(a+b);//
- })();
- //功能B
- (function(){
- var a = 2;
- var b = 1;
- alert(a-b);//
- })();
[4]此时有了新需求,网页中加入功能C,且需要用到功能A中的变量b。于是在window作用域下定义一个全局变量,把它作为一个桥梁,完成各匿名函数之间的通信
- //全局变量
- var str;
- //功能A
- (function(){
- var a = 1;
- //将b的值赋给str
- var b = str = 2;
- alert(a+b);//
- })();
- //功能B
- (function(){
- var a = 2;
- var b = 1;
- alert(a-b);//
- })();
- //功能C
- (function(){
- //将str的值赋给b
- var b = str;
- alert(b);//
- })();
[5]但如果功能C还需要功能A中的变量a呢,这时就需要再定义一个全局变量
- //全局变量
- var str,str1;
- //功能A
- (function(){
- //将a的值赋给str1
- var a = str1 = 1;
- //将b的值赋给str
- var b = str = 2;
- alert(a+b);//
- })();
- //功能B
- (function(){
- var a = 2;
- var b = 1;
- alert(a-b);//
- })();
- //功能C
- (function(){
- //将str1的值赋给a
- var a = str1;
- //将str的值赋给b
- var b = str;
- alert(a*b);//
- })();
[6]但随着匿名函数之间需要通信的变量越多,需要的全局变量也就越多。因此需要严格控制全局变量的数量,使用hash对象作为全局变量,可以将需要的变量都作为对象的属性,可以保证全局变量的个数足够少,同时拓展性非常好
- //全局变量
- var GLOBAL = {};
- //功能A
- (function(){
- //将a的值赋给GLOBAL.str1
- var a = GLOBAL.str1 = 1;
- //将b的值赋给GLOBAL.str
- var b = GLOBAL.str = 2;
- alert(a+b);//
- })();
- //功能B
- (function(){
- var a = 2;
- var b = 1;
- alert(a-b);//
- })();
- //功能C
- (function(){
- //将GLOBAL.str1的值赋给a
- var a = GLOBAL.str1;
- //将GLOBAL.str的值赋给b
- var b = GLOBAL.str;
- alert(a*b);//
- })();
[7]但如果新增功能D,功能D需要和功能B通信,并使用功能B脚本中的变量a,开发功能D的是工程师丁
- //全局变量
- var GLOBAL = {};
- //功能A
- (function(){
- //将a的值赋给GLOBAL.str1
- var a = GLOBAL.str1 = 1;
- //将b的值赋给GLOBAL.str
- var b = GLOBAL.str = 2;
- alert(a+b);//
- })();
- //功能B
- (function(){
- //将a的值赋给GLOBAL.str1
- var a = GLOBAL.str1 = 2;
- var b = 1;
- alert(a-b);//
- })();
- //功能C
- (function(){
- //将GLOBAL.str1的值赋给a
- var a = GLOBAL.str1;
- //将GLOBAL.str的值赋给b
- var b = GLOBAL.str;
- alert(a*b);//
- })();
- //功能D
- (function(){
- //将GLOBAL.str1的值赋给a
- var a = GLOBAL.str1;
- alert(a*2);//
- })();
[8]由于工程师丁只关心自己的匿名函数和功能B的匿名函数,使用GLOBAL.str却无意中覆盖了功能A中设置的同名变量,导致功能C出错。于是使用命名空间来解决这个问题,在不同的匿名函数下,根据功能声明一个不同的命名空间,然后每个匿名函数中的GLOBAL对象的属性都不要直接挂在GLOBAL对象上,而是挂在此匿名函数的命名空间下
- //全局变量
- var GLOBAL = {};
- //功能A
- (function(){
- GLOBAL.A = {};
- //将a的值赋给GLOBAL.A.str1
- var a = GLOBAL.A.str1 = 1;
- //将b的值赋给GLOBAL.A.str
- var b = GLOBAL.A.str = 2;
- alert(a+b);//
- })();
- //功能B
- (function(){
- GLOBAL.B = {};
- //将a的值赋给GLOBAL.B.str1
- var a = GLOBAL.B.str1 = 2;
- var b = 1;
- alert(a-b);//
- })();
- //功能C
- (function(){
- //将GLOBAL.A.str1的值赋给a
- var a = GLOBAL.A.str1;
- //将GLOBAL.A.str的值赋给b
- var b = GLOBAL.A.str;
- alert(a*b);//
- })();
- //功能D
- (function(){
- //将GLOBAL.B.str1的值赋给a
- var a = GLOBAL.B.str1;
- alert(a*2);//
- })();
[9]如果同一个匿名函数中的程序非常复杂,变量名很多,命名空间还可以进一步拓展,生成二级命名空间
- //以功能A为例
- (function(){
- var a = 1, b = 2;
- GLOBAL.A = {};
- GLOBAL.A.CAT = {};
- GLOBAL.A.DOG = {};
- GLOBAL.A.CAT.name = 'mimi';
- GLOBAL.A.DOG.name = 'xiaobai';
- GLOBAL.A.CAT.move = function(){};
- GLOBAL.A.str1 = a;
- GLOBAL.B.str = b;
- })();
[10]因为生成命名空间是个非常常用的功能,进一步将生成命名空间的功能定义成一个函数,方便调用,完整版本改写后的代码如下
- var GLOBAL = {};
- GLOBAL.namespace = function(str){
- var arr = str.split('.');
- var o = GLOBAL;
- var start = 0;
- if(arr[0] == 'GLOBAL'){
- start = 1;
- }else{
- start = 0;
- }
- for(var i = start; i < arr.length; i++){
- o[arr[i]] = o[arr[i]] || {};
- o = o[arr[i]];
- }
- };
- //功能A
- (function(){
- var a = 1;
- var b = 2;
- GLOBAL.namespace('A.CAT');
- GLOBAL.namespace('A.DOG');
- GLOBAL.A.CAT.name = 'mimi';
- GLOBAL.A.DOG.name = 'xiaobai';
- GLOBAL.A.CAT.move = function(){};
- GLOBAL.A.str1 = a;
- GLOBAL.A.str = b;
- alert(a+b);//
- })();
- //功能B
- (function(){
- var a = 2;
- var b = 1;
- GLOBAL.namespace('B');
- GLOBAL.B.str1 = a;
- alert(a-b);//
- })();
- //功能C
- (function(){
- var a = GLOBAL.A.str1;
- var b = GLOBAL.A.str;
- alert(a*b);//
- })();
- //功能D
- (function(){
- var a = GLOBAL.B.str1;
- alert(a*2);//
- })();
[11]代码的冲突问题已经解决了,但可维护性并不强。比如,现在需要让工程师甲去修改功能B。因为工程师甲写的脚本是关于功能A的,他并不知道功能B的脚本情况。为了改善这种局面,需要给代码添加适当的注释。
- var GLOBAL = {};
- GLOBAL.namespace = function(str){
- var arr = str.split('.');
- var o = GLOBAL;
- var start = 0;
- if(arr[0] == 'GLOBAL'){
- start = 1;
- }else{
- start = 0;
- }
- for(var i = start; i < arr.length; i++){
- o[arr[i]] = o[arr[i]] || {};
- o = o[arr[i]];
- }
- };
- /*
- * @method 功能A:实现加法运算
- * @author 工程师甲
- * @connect 1234567
- * @time 2015-01-01
- */
- (function(){
- var a = 1;
- var b = 2;
- GLOBAL.namespace('A.CAT');
- GLOBAL.namespace('A.DOG');
- GLOBAL.A.CAT.name = 'mimi';
- GLOBAL.A.DOG.name = 'xiaobai';
- GLOBAL.A.CAT.move = function(){};
- GLOBAL.A.str1 = a;
- GLOBAL.A.str = b;
- alert(a+b);//
- })();
- /*
- * @method 功能B:实现减法运算
- * @author 工程师乙
- * @connect 1234567
- * @time 2015-01-01
- */
- (function(){
- var a = 2;
- var b = 1;
- GLOBAL.namespace('B');
- GLOBAL.B.str1 = a;
- alert(a-b);//
- })();
- /*
- * @method 功能C:实现乘法运算
- * @author 工程师丙
- * @connect 1234567
- * @time 2015-01-01
- */
- (function(){
- var a = GLOBAL.A.str1;
- var b = GLOBAL.A.str;
- alert(a*b);//
- })();
- /*
- * @method 功能D:实现乘2运算
- * @author 工程师丁
- * @connect 1234567
- * @time 2015-01-01
- */
- (function(){
- var a = GLOBAL.B.str1;
- alert(a*2);//
- })();
让javascript不再冲突,需要
- [1]避免全局变量的泛滥
- [2]合理使用命名空间
- [3]为代码添加必要的注释
js避免命名冲突的更多相关文章
- js文件命名冲突理解
在一个index.html文件里先后导入a.js和b.js文件a.js文件里写上var s = 2;console.log(s);b.js文件里写上var s = 5;这时a.js和b.js用了相同的 ...
- JS的解析与执行过程—全局预处理阶段之命名冲突的处理策略
有如下代码: <body> <script> alert(f); function f() { console.log("fff"); } var f = ...
- Jquery库及其他库之间的$命名冲突解决办法
首先我们应该知道,在jquery中,$(美元符号)就是jquery的别名,也就是说使用$和使用jquery是一样的,在很多时候我们命名空间时,正是因为这个$而产生的冲突的发生.比如说:$('#xmla ...
- javascript 闭包暴露句柄和命名冲突的解决方案
暴露 最近在琢磨前端Js开源项目的东西,然后就一直好奇他们是怎么句柄暴露出来的,特整理一下两种方法. 将对象悬挂到window下面. 不使用var进行变量声明.下面上代码: (function(win ...
- JavaScript发展史,与JScript差别,引入方式,数据类型,命名规范,命名推荐,解决命名冲突
文件夹: 1.JavaScript发展史 2.JavaScript与JScript差别 3.JavaScript引入方式 4.JavaScript基本数据类型及布尔值 5.JavaScript命名规范 ...
- jquery源码中noConflict(防止$和jQuery的命名冲突)的实现原理
jquery源码中noConflict(防止$和jQuery的命名冲突)的实现原理 最近在看jquery源码分析的视频教学,希望将视频中学到的知识用博客记录下来,更希望对有同样对jquery源码有困惑 ...
- css命名冲突解决方法
css的命名冲突目前有几种解决方法: 1.命名约定 人为的制定一下命名规则以避免冲突,例如前缀,嵌套等 2.CSS in JS 在JavaScript中写CSS,使用工具编译为css,最常见的是sty ...
- css 命名冲突 & solution
css 命名冲突 & solution 类似这样,为了解决模块间可能存在的 css 命名冲突问题,需要单独提供给模块开发者一套模块开发环境:同时,文档上要有如何使用的规范说明. CSS 建议: ...
- js的命名规范
js的命名规范 1.驼峰命名法:首字母是小写的,接下来的字母都以大写字符开头.例如: var testValue = 0; var oneValue = 10; 2. ...
随机推荐
- matlab 学习之常用函数2
-----------------------------author:midu ---------------------------qq:1327706646 ------------------ ...
- 【Android】带底部指示的自定义ViewPager控件
在项目中经常需要使用轮转广告的效果,在android-v4版本中提供的ViewPager是一个很好的工具,而一般我们使用Viewpager的时候,都会选择在底部有一排指示物指示当前显示的是哪一个pag ...
- django使用自己的setting的方法
创建一个自己的setting xxx.setting export DJANGO_SETTINGS_MODULE="xxx.setting" 然后在项目中import原生的sett ...
- java 对象变量 c++对象指针 初始化对象变量的2中方法
java 对象变量 c++对象指针 java null引用 c++ null指针 Date deadline 是 对象变量,它可以引用Date类型的对象,但它不是一个对象,实际上它也没有引用对象. ...
- 使用cocos2d-js-3.0RC1中的物理引擎chipmunk模拟的“别碰钉子”源码分享(含碰撞检测)
分别用box2d和chipmunk实现了一下,不过box2d没整理,也懒得整理了.chipmunk整理了一下,分享给大家吧. 刚开始研究,抛砖引玉 简要说明:1.初始化物理环境,增加边界 initPh ...
- php调用短网址接口
<?php $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,"http://dwz.cn/create.php"); curl_se ...
- 【题解】cycle
[题解]cycle 题目描述 给定一个无向图,求一个环,使得环内边权\(\div\)环内点数最大. 数据范围 \(n \le 5000\) \(m\le 10000\) \(Solution\) 考虑 ...
- 爬虫之重要的requests模块
一 . requests模块 什么是requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能强大,用法简洁高效.在爬虫领域中占据着半 ...
- iOS 开发实践之 Auto Layout
原:http://xuexuefeng.com/autolayout/?utm_source=tuicool 本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自 ...
- Android Weekly Notes Issue #319
Android Weekly Issue #319 July 22nd, 2018. Android Weekly Issue #319 本期内容包括: MotionLayout加动画; Kotlin ...