JS学习笔记:JavaScript匿名函数与闭包(closure)
2016-03-03 23:38
609 查看
学JavaScript有段时间了,遇到闭包问题有时还是会犯错,最近在整理笔记,也以此来加深理解。
这部分之所以会放在一起整理,是因为匿名函数和闭包的概念很容易混淆,经常会用错。
闭包作为JavaScript的一个难点,也是它的一个特色,很多高级应用都要通过闭包实现,正确的理解和使用闭包是很重要的。闭包是建立在匿名函数之上的,所以先要正确了解匿名函数。
匿名函数
匿名函数简单来说就是没有函数名的函数。
先看一个普通函数的例子:
这个函数如果匿名会是:
匿名函数赋值:
函数里的匿名函数:
闭包
简单来讲,闭包就是能够读取其他函数内部变量的函数。
闭包是指有权访问另一个函数作用域中的变量的函数, 创建闭包的常见的方式, 就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
写一个通过闭包返回局部变量的例子:
闭包的用途
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
例如:通过匿名函数实现累加
使用闭包的注意点
1)使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。同时,由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存。过度使用闭包会导致性能下降,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。PS:如果并没有使用解除引用,那么需要等到浏览器关闭才得以释放。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
3)在闭包中使用 this 对象也可能会导致一些问题,this 对象是在运行时基于函数的执行环境绑定的,如果 this 在全局范围就是 window,如果在对象内部就指向这个对象。而闭包却在运行时指向 window 的,因为闭包并不属于这个对象的属性或方法。
这部分之所以会放在一起整理,是因为匿名函数和闭包的概念很容易混淆,经常会用错。
闭包作为JavaScript的一个难点,也是它的一个特色,很多高级应用都要通过闭包实现,正确的理解和使用闭包是很重要的。闭包是建立在匿名函数之上的,所以先要正确了解匿名函数。
匿名函数
匿名函数简单来说就是没有函数名的函数。
先看一个普通函数的例子:
function f1() { //函数名是 f1
return 'f1()'; }
这个函数如果匿名会是:
function () { //匿名函数,会报错
return 'noname'; }
匿名函数赋值:
var f1 = function () { //将匿名函数赋给变量 return 'f1'; }; alert(f1()); //调用方式和函数调用相似
函数里的匿名函数:
function box () { return function () { //函数里的匿名函数,产生闭包 return 'Lee'; } } alert(box()()); //调用匿名函数
闭包
简单来讲,闭包就是能够读取其他函数内部变量的函数。
闭包是指有权访问另一个函数作用域中的变量的函数, 创建闭包的常见的方式, 就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
写一个通过闭包返回局部变量的例子:
function f1() { var user = 'Lee'; return function () { //通过匿名函数返回 f1()局部变量 return user; }; } alert(f1()()); //通过f1()()来直接调用匿名函数返回值 var f= f1(); alert(f()); //另一种调用匿名函数返回值
闭包的用途
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
例如:通过匿名函数实现累加
var age = 100; return function () { age ++; return age; } } var b = box(); //获得函数 alert(b()); //调用匿名函数 alert(b()); //第二次调用匿名函数,实现累加
使用闭包的注意点
1)使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。同时,由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存。过度使用闭包会导致性能下降,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。PS:如果并没有使用解除引用,那么需要等到浏览器关闭才得以释放。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
3)在闭包中使用 this 对象也可能会导致一些问题,this 对象是在运行时基于函数的执行环境绑定的,如果 this 在全局范围就是 window,如果在对象内部就指向这个对象。而闭包却在运行时指向 window 的,因为闭包并不属于这个对象的属性或方法。
相关文章推荐
- angular.js 动态插入删除dom节点
- jstat
- 有关JSon的用法
- JavaScript学习笔记——数据类型
- JS里获取到for循环中i的实时值。
- javascript 美术馆
- JSONP跨域原理及示例
- Jsp如何实现网页的重定向
- JavaScript王者归来04
- javascript 构造函数中的属性与原型上属性优先级的比较
- 一个小画板(使用canvas)
- JS操作select标签
- javascript学习----关于字符串类的隐性转换
- 我的第一篇jsp文章
- js入门
- js数组的使用
- ExtJS superclass.constructor.call(this, config)
- Javascript面向对象与原型
- [Ext JS 4] Extjs 之 initComponent 和 constructor的区别
- javascript中的prompt()用法