解决全局变量污染
2016-10-10 18:09
183 查看
1、之前的问题:
用过jQuery的人就知道其主要的变量符号就是$没错因此很多项目的开发人
员也要学就自己把$定义成别的含义了我心里对其是无敌的鄙视跟厌恶。
我曾经拿过一个项目使用jQuery的然后上头要我使用一个已有的富文本编辑
器这样就有两个JS文件了
jquery.js和editor.js于是我要开始写该页面的逻辑了我发现editor.js
里边自定义了$符号我原本想要把它直接替换成别的标志符但是悲剧的是
它还有一些插件也会用到混乱的结构导致我花了很多时间去解决这个冲突。
2、全局Window
我们都知道在文件中直接定义的变量跟函数不嵌套在任何域底下的都是属
于全局的也就是都在当前页面的window变量底下。例如:
Js代码 :
可以通过以下三种办法访问到它们:
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代码:
当离开了这个函数域之后tmp等局部变量被销毁只要不要存在在闭包里边
程序员A定义的东西通通挂到了变量window.A底下从而减少了很多污染避免了不
必要的冲突。
回到过去:
再次回到刚刚提过的那个经历如果我现在为editor.js整个包围在function
里边通过这种方式把$给隐藏在一个包里边在它的其他控件中也采取这样的
做法当然还要做一小点改动
Js代码
1. /* editor.js */
2. (function(obj){
3. /* 原先editor里边的内容 */
4. /* 里边有定义了自己的$标志 */
5.
6. obj.editor = obj.editor || {};//如果没有editor对象则生成一个空对象
7. obj.editor.$ = $;//把$挂在全局的editor对象上
8. })(window);
Js代码
1. /* 其他控件.js */
2. (function(obj){
3. var $ = obj.$;//把$恢复
4.
5. /* 原先控件的内容 */
6.
7. })(window.editor);
当然咯,如果editor.js有些功能需要暴露到全局的话还需要将其进一步的挂
在editor变量底下这里只是一个示范。
用过jQuery的人就知道其主要的变量符号就是$没错因此很多项目的开发人
员也要学就自己把$定义成别的含义了我心里对其是无敌的鄙视跟厌恶。
我曾经拿过一个项目使用jQuery的然后上头要我使用一个已有的富文本编辑
器这样就有两个JS文件了
jquery.js和editor.js于是我要开始写该页面的逻辑了我发现editor.js
里边自定义了$符号我原本想要把它直接替换成别的标志符但是悲剧的是
它还有一些插件也会用到混乱的结构导致我花了很多时间去解决这个冲突。
2、全局Window
我们都知道在文件中直接定义的变量跟函数不嵌套在任何域底下的都是属
于全局的也就是都在当前页面的window变量底下。例如:
Js代码 :
<span style="font-size:18px;">function test1(){ } var name; function test2(){ i=1; }</span>上边代码中的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代码:
<span style="font-size:18px;">(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);</span>
当离开了这个函数域之后tmp等局部变量被销毁只要不要存在在闭包里边
程序员A定义的东西通通挂到了变量window.A底下从而减少了很多污染避免了不
必要的冲突。
回到过去:
再次回到刚刚提过的那个经历如果我现在为editor.js整个包围在function
里边通过这种方式把$给隐藏在一个包里边在它的其他控件中也采取这样的
做法当然还要做一小点改动
Js代码
1. /* editor.js */
2. (function(obj){
3. /* 原先editor里边的内容 */
4. /* 里边有定义了自己的$标志 */
5.
6. obj.editor = obj.editor || {};//如果没有editor对象则生成一个空对象
7. obj.editor.$ = $;//把$挂在全局的editor对象上
8. })(window);
Js代码
1. /* 其他控件.js */
2. (function(obj){
3. var $ = obj.$;//把$恢复
4.
5. /* 原先控件的内容 */
6.
7. })(window.editor);
当然咯,如果editor.js有些功能需要暴露到全局的话还需要将其进一步的挂
在editor变量底下这里只是一个示范。
相关文章推荐
- 51单片机解决中断和主程序共享全局变量的方法
- javascript中运用闭包和自执行函数解决大量的全局变量问题
- c语言全局变量和局部变量问题及解决汇总
- 全局变量在多个C文件中公用的解决办法
- 把全局变量定义在.h文件中的引起连接错误的原因以及解决办法
- php 应用程序全局变量解决方法
- 写了一个程序,但是引用了大量的static变量和全局变量,有什么好的方法解决?
- jquery ajax 异步调用方法中不能给全局变量赋值的原因及解决办法
- AJAX回调函数内部给全局变量赋值的问题与解决
- 解决Ajax全局变量赋值的问题
- 网博士解决全局变量不开启问题
- 360提示DedeCms全局变量覆盖漏洞(临时解决方法)
- 全局变量相互依赖和初始化顺序的解决办法
- c#的全局变量解决方法
- 关于DLL工程中存在全局变量可能导致MFC内存泄露误报的原因分析及解决办法
- javascript中运用闭包和自执行函数解决大量的全局变量问题
- jquery 异步调用方法中不能给全局变量赋值的原因及解决办法
- 远离ExtJS 全局变量污染
- 减少全局变量污染 -- javacript语言精粹
- 解决skia静态库中关于jpeg/png编码解码器的全局变量的问题