JavaScript防止全局变量污染的方法总结


Posted in Javascript onAugust 02, 2018

本文实例讲述了JavaScript防止全局变量污染的方法。分享给大家供大家参考,具体如下:

javaScript 可以随意定义保存所有应用资源的全局变量。但全局变量可以削弱程序灵活性,增大了模块之间的耦合性。

在多人协作时,如果定义过多的全局变量 有可能造成全局变量冲突,也就是全局变量污染问题,以下是两种解决办法

一. 定义全局变量命名空间

只创建一个全局变量,并定义该变量为当前应用容器,把其他全局变量追加在该命名空间下

var MY={};
my.name={
  big_name:"zhangsan",
  small_name:"lisi"
};
my.work={
  school_work:"study",
  family_work:"we are"
};

二 . 利用匿名函数将脚本包裹起来

(function(){
  var exp={};
  var name="aa";
  exp.method=function(){
    return name;
  };
  window.ex=exp;
})();

前言

记得long long ago,刚刚开始写JS的时候,我喜欢写一些函数在JS文件里边,然后通过script标签引进来,在DOM节点上绑定onclick等事件,看了很多人写的代码,也大多是这样。

后来会发现,当项目小的时候这么做为了快速开发是可以接受的,然而当很多人一起开发一个Javascript大应用的时候,你会发现不同的代码风格跟全局变量会导致很多冲突,这是一个很痛苦的事情。

曾经的经历

用过jQuery的人就知道其主要的变量符号就是$,没错!因此很多项目的开发人员也要学,就自己把$定义成别的含义了,我心里对其是无敌的鄙视跟厌恶。

我曾经拿过一个项目使用jQuery的,然后上头要我使用一个已有的富文本编辑器,这样就有两个JS文件了

jquery.js和editor.js,于是我要开始写该页面的逻辑了,我发现editor.js里边自定义了$符号,我原本想要把它直接替换成别的标志符,但是悲剧的是,它还有一些插件也会用到,混乱的结构导致我花了很多时间去解决这个冲突。

全局Window

我们都知道,在文件中直接定义的变量跟函数(不嵌套在任何域底下的)都是属于全局的,也就是都在当前页面的window变量底下。例如:

JS代码

function test1(){
}
var name;
function test2(){
  i = 1;
}

上边代码中的name,test1,test2和i都是属于window底下的全局变量,也就是可以通过以下三种办法访问到它们:

1.直接访问name,test1()等;

2.使用window["name"], window['test1']()等;

3.使用window.name,window.test1()等。

注意:上边代码中的i虽然是在test2函数里边才出现的,因为其前面没有使用var关键字,解释器会认为它在test2的上一层定义的,依次查找上一层,直到找到window全局,如果发现还是未定义,那么将其挂在window底下成为了全局变量。

所以你直接定义的函数通通都挂到了window底下,这就是一种污染了,当很多人定义各种变量跟函数,你又得同时引入进来的时候,这个冲突的概率就变大了。

减少污染

那为了避免过多这样的冲突,以及模块之间的耦合性更低,需要减少这样的污染。

此时我们会想,那不要把变量定义在全局呗,采用类似C++的命名空间,Java的包的思路就行啦。

首先就是将不同的模块划入到不同的全局“包”(这里的包的概念实际上就是一个Javascript对象而已)。

例如,程序员A为全局添加一个A变量,然后他把自己定义的函数/变量全部挂到A底下,这样就跟程序员B所定义的隔离了。

再者我们可以使用函数域来隔离一些局部变量的冲突,比如说程序员A写的代码如下:

JS代码:

(function(obj){
  /* 在这里边就与外边隔离了,定义的局部变量不会与外界干扰 */
  /* 为了跟外界达到共享的目的,还可以为其加入参数,例如obj,在最后调用的时候把相关的参数传进来,例如下边的window */
  var A = {};//定义一个A包
  var tmp;//临时变量
  A.i = 1;//定义这个包里边的i变量
  A.func = function(){alert('I am A');};
  obj.A = A;/* 把A包挂到obj底下 */
})(window);

当离开了这个函数域之后,tmp等局部变量被销毁(只要不要存在在闭包里边),程序员A定义的东西通通挂到了变量window.A底下,从而减少了很多污染,避免了不必要的冲突。

回到过去

再次回到刚刚提过的那个经历,如果我现在为editor.js整个包围在function里边,通过这种方式把$给隐藏在一个包里边,在它的其他控件中也采取这样的做法,当然还要做一小点改动:

JS代码:

/* editor.js */
(function(obj){
  /* 原先editor里边的内容 */
  /* 里边有定义了自己的$标志 */
  obj.editor = obj.editor || {};//如果没有editor对象,则生成一个空对象
  obj.editor.$ = $;//把$挂在全局的editor对象上
})(window);

JS代码:

/* 其他控件.js */
(function(obj){
  var $ = obj.$;//把$恢复
  /* 原先控件的内容 */
})(window.editor);

当然咯,如果editor.js有些功能需要暴露到全局的话,还需要将其进一步的挂在editor变量底下,这里只是一个示范。

本篇总结

很多框架都采用了这种做法减少全局污染,可能很多人一开始对这种做法有疑惑,这里只是个人理解拿出来分享一下,继续欢迎交流。

更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
JavaScript常用标签和方法总结
Sep 01 Javascript
关于JavaScript作用域你想知道的一切
Feb 04 Javascript
微信小程序 地图map详解及简单实例
Jan 10 Javascript
AngularJS实现的回到顶部指令功能实例
May 17 Javascript
Angular中ng-repeat与ul li的多层嵌套重复问题
Jul 24 Javascript
JS 中LocalStorage和SessionStorage的使用
Aug 17 Javascript
微信小程序实现tab和swiper切换结合效果
Jul 17 Javascript
webpack之devtool详解
Feb 10 Javascript
移动端图片上传旋转、压缩问题的方法
Oct 16 Javascript
Electron 如何调用本地模块的方法
Feb 01 Javascript
vue 进阶之实现父子组件间的传值
Apr 26 Javascript
Vue-axios-post数据后端接不到问题解决
Jan 09 Javascript
微信小程序之自定义组件的实现代码(附源码)
Aug 02 #Javascript
Array数组对象中的forEach、map、filter及reduce详析
Aug 02 #Javascript
利用Blob进行文件上传的完整步骤
Aug 02 #Javascript
vue.js图片转Base64上传图片并预览的实现方法
Aug 02 #Javascript
vue组件横向树实现代码
Aug 02 #Javascript
利用Node.js批量抓取高清妹子图片实例教程
Aug 02 #Javascript
在微信小程序里使用watch和computed的方法
Aug 02 #Javascript
You might like
Phpbean路由转发的php代码
2008/01/10 PHP
PHP 安全检测代码片段(分享)
2013/07/05 PHP
PHP aes (ecb)解密后乱码问题
2015/06/22 PHP
js+xml生成级联下拉框代码
2012/07/24 Javascript
jquery验证手机号码、邮箱格式是否正确示例代码
2013/07/28 Javascript
JQuery下拉框应用示例介绍
2014/04/23 Javascript
JavaScript访问CSS属性的几种方式介绍
2014/07/21 Javascript
javascript中replace( )方法的使用
2015/04/24 Javascript
js实现模拟计算器退格键删除文字效果的方法
2015/05/07 Javascript
JQuery中节点遍历方法实例
2015/05/18 Javascript
javascript使用输出语句实现网页特效代码
2015/08/06 Javascript
javascript日期处理函数,性能优化批处理
2015/09/06 Javascript
jquery拖拽效果完整实例(附demo源码下载)
2016/01/14 Javascript
微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决
2016/12/14 Javascript
详解Vue 中 extend 、component 、mixins 、extends 的区别
2017/12/20 Javascript
浅谈vue项目重构技术要点和总结
2018/01/23 Javascript
vue中slot(插槽)的介绍与使用
2018/11/12 Javascript
React学习之受控组件与数据共享实例分析
2020/01/06 Javascript
[02:43]DOTA2英雄基础教程 圣堂刺客
2013/12/09 DOTA
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
Python利用递归实现文件的复制方法
2018/10/27 Python
pyqt5 删除layout中的所有widget方法
2019/06/25 Python
Pyinstaller 打包exe教程及问题解决
2019/08/16 Python
python和node.js生成当前时间戳的示例
2020/09/29 Python
python利用opencv保存、播放视频
2020/11/02 Python
python中使用np.delete()的实例方法
2021/02/01 Python
夏威夷灵感服装及配饰:Reyn Spooner
2018/09/18 全球购物
文件中有一组整数,要求排序后输出到另一个文件中
2012/01/04 面试题
生物科学专业个人求职信范文
2013/12/07 职场文书
中专生毕业个人鉴定
2014/02/26 职场文书
2015年民兵整组工作总结
2015/07/24 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
2019年XX公司的晨会制度及流程!
2019/07/23 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS
解决Mysql的left join无效及使用的注意事项说明
2021/07/01 MySQL
python_tkinter弹出对话框创建
2022/03/20 Python