JavaScript 闭包
2015-06-19 12:58
417 查看
JavaScript 闭包
一、变量
1、JavaScript 变量可以是局部变量或全局变量。2、函数可以访问是有函数内部定义的变量,函数也可以访问函数外部定义的变量。
3、在web页面中全局变量属于 window 对象。
4、全局变量可应用于页面上的所有脚本。
5、局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。
6、全局和局部变量即便名称相同,它们也是两个不同的变量。修改其中一个,不会影响另一个的值。
注意:变量声明是如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。函数内部声明变量的时候,一定要使用var命令。
二、变量生命周期
1、全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。2、在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用。
三、JavaScript 内嵌函数
1、所有函数都能访问全局变量。2、在 JavaScript 中,所有函数都能访问它们上一层的作用域。
3、JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。
4、内部函数也可以像其他函数一样引用全局变量。
5、只要存在调用内部函数的可能,JavaScript就需要保留被引用的函数。而且JavaScript运行时需要跟踪引用这个内部函数的所有变量,直到最后一个变量废弃,JavaScript的垃圾收集器才能释放相应的内存空间。
四、JavaScript 闭包
闭包是指有权限访问另一个函数作用域的变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
1.1实例
var add = (function () {var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// 计数器为 3
1.2实例解析
变量 add 指定了函数自我调用的返回字值。自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。
add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。
这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。
计数器受匿名函数的作用域保护,只能通过 add 方法修改。
注意: 闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。
2.1实例(一个经典错误)
页面上有若干个div, 我们想给它们绑定一个onclick方法,于是有了下面的代码:<div id="divTest">
<span>0</span> <span>1</span> <span>2</span> <span>3</span>
</div>
<div id="divTest2">
<span>0</span> <span>1</span> <span>2</span> <span>3</span>
</div>
$(document).ready(function() {
var spans = $("#divTest span");
for (var i = 0; i < spans.length; i++) {
spans[i].onclick = function() {
alert(i);
}
}
});
很简单的功能可是却偏偏出错了,每次alert出的值都是4,简单的修改就好使了
var spans2 = $("#divTest2 span");
$(document).ready(function() {
for (var i = 0; i < spans2.length; i++) {
(function(num) {
spans2[i].onclick = function() {
alert(num);
}
})(i);
}
});
2.2实例解析
for (var i = 0; i < spans.length; i++) { spans[i].onclick = function() { alert(i); } }上面代码在页面加载后就会执行,当i的值为4的时候,判断条件不成立,for循环执行完毕,但是因为每个span的onclick方法这时候为内部函数,所以i被闭包引用,内存不能被销毁,i的值会一直保持4,直到程序改变它或者所有的onclick函数销毁(主动把函数赋为null或者页面卸载)时才会被回收。这样每次我们点击span的时候,onclick函数会查找i的值(作用域链是引用方式),一查等于4,然后就alert给我们了。而第二种方式是使用了一个立即执行的函数又创建了一层闭包,函数声明放在括号内就变成了表达式,后面再加上括号括号就是调用了,这时候把i当参数传入,函数立即执行,num保存每次i的值。
使用闭包的注意点:
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
相关文章推荐
- Js setInterval使用
- js数组
- js 取整
- JS array 数组详解
- crockford总结的精华版javascript
- javascript 简单高效判断数据类型
- javascript与html代码相结合的方式
- jsp的两种开发模式
- js 生成随机数
- JS中关于in运算符
- javascript 数据类型转换(parseInt,parseFloat)
- js判断客户端设备类型
- json 串排序 遇到的问题 安照日期倒序 等解决 (按照里面日期字段倒序)
- js常用DOM操作
- 一个不错的js loading源码
- javascript返回顶部插件+源码
- 使用grunt构建seajs教程一
- javascript 推箱子游戏介绍及问题
- JavaScript中的两种全局对象
- JavaScript Type Conversion