防止js全局变量污染方法总结
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变量底下。例如:
function test1(){
} var name; function test2(){
i = ;
}
上边代码中的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写的代码如下:
(function(obj){
/* 在这里边就与外边隔离了,定义的局部变量不会与外界干扰 */
/* 为了跟外界达到共享的目的,还可以为其加入参数,例如obj,在最后调用的时候把相关的参数传进来,例如下边的window */ var A = {};//定义一个A包
var tmp;//临时变量 A.i = ;//定义这个包里边的i变量
A.func = function(){alert('I am A');}; obj.A = A;/* 把A包挂到obj底下 */ })(window);
当离开了这个函数域之后,tmp等局部变量被销毁(只要不要存在在闭包里边),程序员A定义的东西通通挂到了变量window.A底下,从而减少了很多污染,避免了不必要的冲突。
回到过去
再次回到刚刚提过的那个经历,如果我现在为editor.js整个包围在function里边,通过这种方式把$给隐藏在一个包里边,在它的其他控件中也采取这样的做法,当然还要做一小点改动:
/* editor.js */
(function(obj){
/* 原先editor里边的内容 */
/* 里边有定义了自己的$标志 */ obj.editor = obj.editor || {};//如果没有editor对象,则生成一个空对象
obj.editor.$ = $;//把$挂在全局的editor对象上
})(window);
/* 其他控件.js */
(function(obj){
var $ = obj.$;//把$恢复 /* 原先控件的内容 */ })(window.editor);
当然咯,如果editor.js有些功能需要暴露到全局的话,还需要将其进一步的挂在editor变量底下,这里只是一个示范。
本篇总结
很多框架都采用了这种做法减少全局污染,可能很多人一开始对这种做法有疑惑,这里只是个人理解拿出来分享一下,继续欢迎交流。
本文转载自CSDN博客--
防止js全局变量污染方法总结的更多相关文章
- [转] 防止js全局变量污染方法总结
javaScript 可以随意定义保存所有应用资源的全局变量.但全局变量可以削弱程序灵活性,增大了模块之间的耦合性.在多人协作时,如果定义过多的全局变量 有可能造成全局变量冲突,也就是全局变量污染问题 ...
- 防止js全局变量污染方法总结-待续
javaScript 可以随意定义保存所有应用资源的全局变量.但全局变量可以削弱程序灵活性,增大了模块之间的耦合性.在多人协作时,如果定义过多的全局变量 有可能造成全局变量冲突,也就是全局变量污染问题 ...
- js全局变量污染
一.定义全局变量命名空间 只创建一个全局变量,并定义该变量为当前应用容器,把其他全局变量追加在该命名空间下 var my={}; my.name={ big_name:"zhangsan&q ...
- js常见的方法
Ajax请求 jquery ajax函数 我自己封装了一个ajax的函数,代码如下: var Ajax = function(url, type success, error) { $.ajax({ ...
- 为什么不能在 body 标签的前面的 script 标签中定义 JS 全局变量?
<!DOCTYPE html> <!-- 为什么不能在 body 标签的前面的 script 标签中定义 JS 全局变量? 在全局环境下的代码就是在页面加载阶段从上到下一边加载一边执 ...
- vue + typescript,定义全局变量或者方法
众所周知,在 vue中,如果想定义一个全局变量的方法很简单,直接在 vue的原型上挂载属性或者方法即可. 但是,加上了typescript之后, Vue.prototype.$xxx = xxx 这 ...
- TODO:Node.js pm2使用方法
TODO:Node.js pm2使用方法 pm2 是一个带有负载均衡功能的Node应用的进程管理器. 当你要把你的独立代码利用全部的服务器上的所有CPU,并保证进程永远都活着,0秒的重载, PM2是完 ...
- 【转载】JS中bind方法与函数柯里化
原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...
- 前端Js跨域方法汇总—剪不断,理还乱,是跨域
1.通过jsonp跨域2.通过修改document.domain来跨子域(iframe)3.隐藏的iframe+window.name跨域4.iframe+跨文档消息传递(XDM)5.跨域资源共享 C ...
随机推荐
- 如何优雅地实现Python通用多线程/进程并行模块
当单线程性能不足时,我们通常会使用多线程/多进程去加速运行.而这些代码往往多得令人绝望,需要考虑: 如何创建线程执行的函数? 如何收集结果?若希望结果从子线程返回主线程,则还要使用队列 如何取消执行? ...
- golang实现dns域名解析(三):响应报文分析
前面说了构造请求发送报文,接下来我们好好研究下如何解析服务器端发回来的应答信息. 首先还是用前面的程序代码发一个请求,用抓包工具看看应答的内容有哪些: 截图的第一部分是返回信息的统计,表明这个返回的包 ...
- 几大排序思想(由javascript编写)
Hello!我是super喵二~~~今天练了几道面试题,突然觉得好久没有好好归纳 过排序算法了.以前都是用C/java编写排序,这次用js来总结下五大排序算法吧: 1.冒泡排序(常用及常考排序算法): ...
- 【web前端开发】浏览器兼容性处理
1.居中问题div里的内容,IE默认为居中,而FF默认为左对齐,可以尝试增加代码margin: 0 auto;2.高度问题两上下排列或嵌套的div,上面的div设置高度(height),如果div里的 ...
- springboot问题:解决异常Unable to start embedded container;
使用eclipse创建springboot练习时,当主函数与控制器同时写在同一个类时,启动项目正常运行,而当把主函数单独放在一个类中时,无论是与控制器同包还是控制器所在的包是其子包,都报: org.s ...
- 利用npm安装/删除/发布/更新/撤销发布包 --社会我npm哥,好用话不多
一.什么是npm? npm是javascript的包管理工具,是前端模块化下的一个标志性产物 简单地地说,就是通过npm下载模块,复用已有的代码,提高工作效率 1.从社区的角度:把针对某一特定 ...
- css样式表的选择器与分类
css 样式表的作用: 主要用于结构,样式与行为,CSS主要的作用就是美化网页的一个语言,它的特点: 1.结构与样式分离的方式,便于后期维护与改版; 2.样式定义精确到像素的级别; css样式表的结构 ...
- Markdown软件推荐--Typora
非常适合记录笔记. ▌ 所见即所得+所写即所得 Ctrl+/快捷键,转换成纯代码界面. ▌ CSS自设置样式 1.Theme下自带样式系列 2.File- Preference中选择Open Them ...
- FullCalendar 日历插件中文说明文档
FullCalendar提供了丰富的属性设置和方法调用,开发者可以根据FullCalendar提供的API快速完成一个日历日程的开发,本文将FullCalendar的常用属性和方法.回调函数等整理成中 ...
- ios在Xcode里关于图片的权限设置
<key>NSPhotoLibraryUsageDescription</key> <string>This app requires access to the ...