警惕javascript变量的全局污染问题
作用域的概念总是和变量形影不离,它不是javascript语言独有的概念,只是其运用上与其他大型语言略有不同,JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。
JavaScript对作用域的运用与其他语言略有不同,然而总体概念是一致的。作用域限定了javascript文档中的各个资源的可用范围,决定了你定义变量的位置。使用一个匿名函数来容纳所需的变量就是个很好的方法。所有在函数中定义的变量都只应该在该函数的作用域内生效。(变量的作用域会自动向下延伸,这是闭包的概念)
再声明全局作用域的变量,无论何时都能被所有函数所使用,这是个非常诱人的特性,但是对全局作用域的过度使用会造成全局作用域污染,这倒是我们用光所有的合适的变量名,也会导致长久占用内存空间,从而很难创建出一个能够长久维护的应用来。所以,对全局作用域的使用一定要少而谨慎。
比如,以下的全局污染示例:
//全局作用域污染示例
var party = "starlen";
//我创建了一个全局作用域变量
function pizzaParty(totalSlices,peopleCount) {
"use strict"; var fairness = totalSlices * peopleCount;
return fairness;
} (function () {
"use strict"; var body = document.getElementsByTagName("body")[0]; body.innerHTML = "'<p>' '<a href='*'>'partyStarty(26,18) '</a>'+partyStarter+'</p>'";
})();
全局变量与任何编程语言中的其他东西一样,也有其用途。然而对他的使用尤需谨慎,而且在用之前必须仔细的思量其内容及名称。使用全局变量来设定程序的全局配置数据是个比较好的办法,全局配置包括:基地址(base URL)、目录信息、程序名称,或是一些需要反复使用而重复定义又会造成资源浪费的东西,应该利用每一件东西的长处,而不应该滥用。
现在,我将这个变量移动到了匿名函数之中,以清理该文档的全局作用域。合适的位置看起来也更加顺眼,并且在该函数执行完毕时会立即销毁变量,不会占用内存的宝贵资源。
//局部变量作用域 function Party(totalSlices,peopleCount) {
"use strict"; var fairness = totalSlices * peopleCount;
return fairness;
} (function () {
"use strict"; var partyStarter = "starlen";
//现在,这个变量的作用域只归此闭包函数所有
var body = document.getElementsByTagName("body")[0]; body.innerHTML = "'<p>' '<a href='*'>'partyStarty(24,16) '</a>'+partyStarter+'</p>'";
})();
作用域问题,在javascript中,作用域与其他的面向对象编程语言不太一样,它的作用域是由函数划分的,不是由块划分(while,for,if中间),还有一个特性是所有属于全局作用域的变量都是window对象的属性。
//作用域
var fruit = "apple"; //全局变量,并属于全局作用域 if(true){ var fruit = "new apple"; //改变全局变量的值,它现在仍处于全局作用域
}
alert( fruit == "new apple"); //fruit的最终值是new apple function apple(){
var fruit = "old apple"; //使用一个函数来更改它的值
}
apple(); alert( fruit == "new apple"); //最后发现,apple函数没有起作用 alert(window.fruit == "new apple"); //全局变量fruit和window对象的fruit属性一致
虽然javascript中的作用域规则不如块级作用域那么严格(没有深入研究JS的程序员因此会批评它),但它是非常强大的,而且功能完备,在于闭包概念一起使用时,javascript就能表现出这个脚本语言的强大本色。
//隐式全局作用域变量声明 function apple(){
fruit = "apple"; //fruit变量处于apple函数作用域
}
apple(); alert(window.fruit == "apple"); //但是使用window对象会发现,fruit已经处于全局作用域 //闭包
var obj = document.getElementById("main"); var items = ["click","keypress"]; //给变量绑定一个数组 for(var i = 0;i < items.length;i++ ){ //循环遍历数组每一个元素
//闭包函数激发作用域
(function(){
item = items[i]; //在此引用全局变量,记住当前的值 obj["on"+item] = function(){ //item引用本for循环上下文所属作用域中的父变量
alert("这是一个交互动作"+ item);
}
})();
}
闭包概念相对复杂,它意味着内层的函数可以引用存在于包围他的函数的变量,深入研究并理解它,控制变量的作用域,就能避免作用域的污染问题。
警惕javascript变量的全局污染问题的更多相关文章
- javascript变量:全局?还是局部?这个得注意!
做项目就是一个学习的过程! 做为一个学习C3年多,从C程序员转前端的人来说,javascript中的许多规则是没办法或者说一时半会理解不了的. 今天就遇到了一个,大致就是这么个代码. var a ; ...
- javascript变量:全局?还是局部?这个得注意
在JS中.是没有块级作用域的 举两个个样例: if语句块: if (true){ var name='Ling'; } alert(name); 输出:Ling for语句块; for(var ...
- javascript变量作用域 全局及局部
$("#inStartTime").datetimepicker({ format: 'yyyy-mm-dd hh:ii', autoclose: true, todayBtn: ...
- JavaScript变量污染
定义过多的全局变量,有可能造成全局变量冲突,这种现象称为变量污染. 全局变量在全局作用域内外都是可见的.若是已经声明了一个全局变量,再以相同的关键字和标识符重新声明全局变量,后者的赋值会替代前者的赋值 ...
- 六天玩转javascript:javascript变量与表达式(1)
说明 本系列属于进阶系列,语常用语法等不在本系列介绍范围之内. 在我刚开始做一个程序员并开发项目的时候,我总是喜欢使用开发语言的各种特性,每次m$发布新版C#的时候我总是会把开发者预览版下好,亲自体验 ...
- javascript 函数初探 (三)--- javascript 变量的作用域
javascript 变量的作用域: 这是一个至关重要的问题.特别是当我们从别的语言转向javascript时,必须要明白一点,即在javascript中,变量的定义并不是以代码块作为作用域的,而是以 ...
- 深入理解 JavaScript 变量的作用域和作用域链
一个变量的作用域(scope)是程序源代码中定义这个变量的区域.简单的说,作用域就是变量与函数的可访问范围.全局变量拥有全局作用域,在JavaScript代码中的任何地方都有定义.局部变量是在函数体内 ...
- javascript变量的作用域
javascript变量的作用域 基本类型和引用类型 基本类型值指的是简单的数据段,而引用类型值指的是那个可能由多个值组成的对象 讲一个值赋值给变量时,javascript解析器首先要确定是基本类型 ...
- javascript变量声明 及作用域
javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 java ...
随机推荐
- 【jQuery基础学习】03 jQuery中的事件与动画
关于jQuery中的事件 js与HTML之间的交互是通过用户和浏览器操作页面时引发的事件来处理的. jQuery增加并扩展了基本的事件处理机制,jQuery不仅提供了更加优雅的事件处理方法,而且极大地 ...
- phpwind的rewrite重写原理
没有深入过pw,被人问到这方面的问题,搜索了一下,发现了一篇博文,但原博客已打不开. http://www.phpsoho.com/html/document/200608/1154750694.ht ...
- python-set集合类方法
s1=set([11,22,33,44,'Tom','tony',11,77,2.5,])返回的是{11,22,33,44,'Tom','tony',77,2.5}(注意:返回的并不是一个字典,只是告 ...
- MyBatis中的特殊符号[20160713]
今天中午回到工位已经是12:20多了,没有时间睡觉了,本想着还能提前开始,结果看了点新闻之后,又是12:40了,所以新闻坚决不能看,执行力. 今天主要记录一下MyBatis中的特殊符号的问题,这个问题 ...
- [moka同学代码]PHP初级知识:上传文件源码
1.目录结构
- python flask应用部署
失败版本:flask+uwsgi ini配置文件 [uwsgi] callable = app ;//程序内启用的application变量名 home = /home/jcuan/code/pyth ...
- mysql metadata lock锁
很多情况下,很多问题从理论上或者管理上而言都是可以避免或者说很好解决的,但是一旦涉及到现实由于管理或者协调或者规范执行的不够到位,就会出现各种各样本不该出现的问题,这些问题的通常在生产环境并不会出现, ...
- java微信开发
所谓的微信开发就是在微信开发模式之下,对微信进行公众号和企业号的扩展开发. 如果要让你的微信公众号有更多的功能,比如菜单支持,自动的信息服务,查询,消息推送等,就必须开启微信的开发模式.进入微 ...
- GDB调试器使用总结
概述:GDB是linux下调试程序的神器,做为linux程序员,如果不能熟练的使用GDB进行程序调试,那将是很失败的事情.强大的功能使GDB的使用也变得比较复杂,如果是初学者肯定会比繁杂的命令吓到.下 ...
- cl_gui_cfw=>dispatch
将已经触发的EVENT发送给他们各自的EVENT HANDLER,以便让这些事件得到响应. 根据返回值可以判断是否发送成功. CALL METHOD cl_gui_cfw=>dispatch ...