警惕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 ...
随机推荐
- java操作小技巧,遇到过的会一直更新,方便查找
1.<c:forEach>可以循环map array List 2.操纵数组,不知道类型的情况下,不需要判断数组类型,直接用反射,arrays.Class.isArrays() 获取数组长 ...
- dict和set
#dict和set #dict #Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map #使用键-值(key-value)存储,具有极快的查找速度. #字 ...
- 汇编语言--寄存器(cpu工作原理)
本文地址:http://www.cnblogs.com/archimedes/p/assembly-register.html,转载请注明源地址. 本文主要将介绍的是8086 CPU中的寄存器, 寄存 ...
- iOS设计模式之命令模式
命令模式 基本理解 命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化:对请求队列或记录请求日志,以及支持客可撤离的操作. 苹果的Target-Action ...
- JAVA基础学习day23--GUI基础
一.GUI概述 1.1.GUI概述 Graphical User Interface(图形用户接口) 用图形的方式,来显示计算机操作的界面, CLI: Command line User Interf ...
- Web应用程序系统的多用户权限控制设计及实现-用户模块【7】
前五章均是从整体上讲述了Web应用程序的多用户权限控制实现流程,本章讲述Web权限管理系统的基本模块-用户模块.用户模块涉及到的数据表为用户表. 1.1用户域 为了更规范和方便后期系统的二次开发和维护 ...
- 分析实现Android自定义View之扇形图
继承View基类,画了这样的扇形图 直接来步骤吧 (参考了GcsSloop的教程) 1.分析 自定义View需要认真的分析下,里面还是会用到一些数学知识 首先是扇形该怎么表现 1. 扇形的外观是个圆弧 ...
- 斯坦福iOS7公开课7-9笔记及演示Demo
这一部分主要介绍了iOS的绘图.手势.协议.block.力学特效动画(包括重力.碰撞.吸附等)以及自动布局的内容. 1.绘图.手势 (1)调用一个自定义的UIView时,可以使用awakeFromNi ...
- Objective-C之集合对象的内存管理
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 学习C语言的数组
C语言的数组 数组声明的实例:int num[3];只要记下这个模板就好. 不建议使用变量定义数组,如果使用了变量定义数组,作为数组的元素的个数,不初始化的情况下是随机值,如果初始化会直接报错 注意: ...