当前位置: 首页 > 图文教程 > 网络编程 > Javascript > JavaScript 变量作用域及闭包

Javascript
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
(转载)JavaScript中匿名函数,函数直接量和闭包
简单的无缝滚动程序-仅几行代码
Javascript中的数学函数集合
javascript之大字符串的连接的StringBuffer 类
javascript之对系统的toFixed()方法的修正
用javascript实现自定义标签
js在客户端验证密码强度,兼容FireFox和IE
javascript背景颜色按时变换
脚本分析、压缩、混淆工具 JSA新版本发布,压缩效率提高大约10%
javascript语句中的CDATA标签的意义
用javascript实现分割提取页面所需内容
网上抓的一个特效
js之点击 超连接,提示一个层.点击空白.层消失
模拟用户操作Input元素,不会触发相应事件
弹出广告特效代码(一个IP只弹出一次)
(仅IE下有效)关于checkbox 三态
JavaScript Archive Network 集合
关于__defineGetter__ 和__defineSetter__的说明
textContent在Firefox下与innerText等效的属性

Javascript 中的 JavaScript 变量作用域及闭包


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-12   浏览: 324 ::
收藏到网摘: n/a

作用域JavaScript 的变量作用域是按照函数划分的,为了快速的了解它的特性,我们通过实例来进行演示。 实例一:
复制代码 代码如下:
实例六:
复制代码 代码如下:

<script type="text/javascript">
window.onload = function(){
var i = 1;
function test(){
alert(i);
}
// 弹出内容为 1 的提示框
test();
}
</script>

分析:
内部函数可以访问外部函数的变量,这个就引出了一个新的概念,那就是闭包。
闭包
什么是闭包呢,简单的说就是一个函数 A ,它的内部函数 B 可以访问 A 内定义的变量,即使函数 A 已经终止。下面通过实例进行了解。
实例七:
复制代码 代码如下:

<script type="text/javascript">
window.onload = function(){
var i = 1;
window.onunload = function(){
alert(i);
}
}
</script>

分析:
当整个页面加载完成时,会触发 onload 事件,这个onload 事件方法里给窗口的onunload 事件注册了一个方法,这个方法里用到了onload 事件方法里声明的变量,然后onload 事件方法运行结束,这时候我们点击关闭窗口,会弹出内容为1的提示框,说明onunload 的事件方法成功的调用了onload 事件方法里声明的变量。
为了进一步了解闭包的特性,看下面的例子
实例八:
复制代码 代码如下:

<script type="text/javascript">
function initX(oarg){
// 定义一个变量
var x = oarg;
// 定义一个显示变量的方法
var funGet = function(){
alert(x);
}
// 定义一个对变量进行修改的方法
var funSet = function(iarg){
x = iarg;
}
// 返回这两个方法
return [funGet,funSet];
}
// 运行一个方法实例,返回值为包含 get 和 set 方法的数组
var funArr = initX(1);
// 得到 get 方法
var funGet = funArr[0];
// 得到 set 方法
var funSet = funArr[1];
// 运行 get 方法,显示initX方法实例内的 x 变量,结果为 1
funGet();
// 运行 set 方法,对initX方法实例内的 x 变量进行赋值
funSet(2);
// 运行 get 方法,显示initX方法实例内的 x 变量,结果为 2
funGet();
</script>

分析:
当内部函数对外部函数定义的变量进行调用时,实际上引用的是这个变量的内存块,所以当我们调用内部函数时,引用的变量值是当前这个变量的实际内容。
闭包功能虽然强大,但是如果不注意,它也会给我们带来困扰。看下面的例子。
实例九:
复制代码 代码如下:

<button id="main">run</button>
<script type="text/javascript">
(function(){
var obj = document.getElementById("main");
var funArr = ['onclick','onkeypress'];
for(var i=0; i<funArr.length; i++){
var temp = funArr[i];
obj[temp] = function(){
alert(temp);
}
}
})();
</script>

写代码的原意是给 id 是 main 的按钮注册点击事件和按键事件,事件的内容是分别弹出事件名称的提示框。但是结果有点匪夷所思,两个事件的提示框全是 onkeypress,根据闭包的原理,我们仔细分析,就会发现当两个事件方法被调用时 temp 变量 指向的是 funArr[1] 的内容,我们可以这样修改来解决这个问题:
复制代码 代码如下:

<button id="main">run</button>
<script type="text/javascript">
(function(){
var obj = document.getElementById("main");
var funArr = ['onclick','onkeypress'];
for(var i=0; i<funArr.length; i++){
(function(){
var temp = funArr[i];
obj[temp] = function(){
alert(temp);
}
})();
}
})();
</script>

把 for 循环内的代码放入一个函数内,这样,每循环一次都会产生一个函数实例,让函数实例记录 funArr 数组中的每个值,这样就避免了上面碰到的问题。