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 相关文章推荐
基于JQuery的浮动DIV显示提示信息并自动隐藏
Feb 11 Javascript
js日期相关函数总结分享
Oct 15 Javascript
一个仿微博登陆邮箱提示框js开发案例
Jul 28 Javascript
BootStrap tab选项卡使用小结
Aug 09 Javascript
JavaScript实现的鼠标响应颜色渐变效果完整实例
Feb 18 Javascript
详解vue-router基本使用
Apr 18 Javascript
jQuery实现腾讯信用界面(自制刻度尺)样式
Aug 15 jQuery
Spring Boot/VUE中路由传递参数的实现代码
Mar 02 Javascript
JavaScript作用域、闭包、对象与原型链概念及用法实例总结
Aug 20 Javascript
记一次react前端项目打包优化的方法
Mar 30 Javascript
Javascript模块化机制实现原理详解
Apr 02 Javascript
vue中div禁止点击事件的实现
Apr 02 Vue.js
微信小程序之自定义组件的实现代码(附源码)
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
PHP文章采集URL补全函数(FormatUrl)
2012/08/02 PHP
浅析PHP中strlen和mb_strlen的区别
2014/08/31 PHP
8个PHP数组面试题
2015/06/23 PHP
yii使用bootstrap分页样式的实例
2017/01/17 PHP
laravel model模型处理之修改查询或修改字段时的类型格式案例
2019/10/17 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
2019/12/25 PHP
IE6与IE7中,innerHTML获取param的区别
2009/03/15 Javascript
JS判断数组中是否有重复值得三种实用方法
2013/08/16 Javascript
node.js中使用node-schedule实现定时任务实例
2014/06/03 Javascript
node.js中的url.parse方法使用说明
2014/12/10 Javascript
JS动态显示表格上下frame的方法
2015/03/31 Javascript
js焦点文字滚动效果代码分享
2015/08/25 Javascript
深入了解JavaScript的逻辑运算符(与、或)
2016/12/20 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
微信小程序开发之IOS和Android兼容的问题
2017/09/26 Javascript
在Swiper内如何制作CSS3动画效果示例代码
2017/12/07 Javascript
vue通过指令(directives)实现点击空白处收起下拉框
2018/12/06 Javascript
openlayers4实现点动态扩散
2020/08/17 Javascript
[01:35:53]完美世界DOTA2联赛PWL S3 Magma vs GXR 第二场 12.13
2020/12/17 DOTA
python实现的系统实用log类实例
2015/06/30 Python
Django 源码WSGI剖析过程详解
2019/08/05 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
2020/03/16 Python
tensorflow模型文件(ckpt)转pb文件的方法(不知道输出节点名)
2020/04/22 Python
在Python中实现字典反转案例
2020/12/05 Python
CSS中垂直居中的简单实现方法
2015/07/06 HTML / CSS
英国第一的购买便宜玩具和游戏的在线购物网站:Bargain Max
2018/01/24 全球购物
巴黎卡诗加拿大官网:Kérastase加拿大
2018/11/12 全球购物
美国和加拿大计算机和电子产品购物网站:TigerDirect.com
2019/09/13 全球购物
应届毕业生的个人自我鉴定
2013/10/24 职场文书
怎么写好自荐信
2013/10/30 职场文书
工作失职检讨书(精华篇)
2014/10/15 职场文书
优秀团员自我评价
2015/03/10 职场文书
家长通知书家长意见
2015/06/03 职场文书
《落花生》教学反思
2016/02/16 职场文书
2016年“节能宣传周”活动总结
2016/04/05 职场文书
解决numpy数组互换两行及赋值的问题
2021/04/17 Python