读书频道 > web开发 > Javascript > Effective JavaScript:编写高质量JavaScript代码的68个有效方法
第13条:使用立即调用的函数表达式创建局部作用域
2013-12-07 14:57:46     我来说两句 
收藏    我要投稿   
本书共分为7章,分别涵盖JavaScript的不同主题。第1章主要讲述最基本的主题,如版本、类型转换要点、运算符注意事项和分号局限等。第2章主要讲解变量作用域,介绍此方面的一些基本概念,以及一些最佳实践经验。第  立即去当当网订购

这段程序(Bug程序)输出什么?

 

程序员可能希望这段程序输出10,但实际上它输出undefined值。

搞清楚该例子的方法是理解绑定与赋值的区别。在运行时进入一个作用域,JavaScript会为每一个绑定到该作用域的变量在内存中分配一个“槽”(slot)。wrapElements函数绑定了三个局部变量:result、i和n。因此,当它被调用时,wrapElements函数会为这三个变量分配“槽”。在循环的每次迭代中,循环体都会为嵌套函数分配一个闭包。该程序的Bug在于这样一个事实:程序员似乎期望该函数存储的是嵌套函数创建时变量i的值。但事实上,它存储的是变量i的引用。由于每次函数创建后变量i的值都发生了变化,因此内部函数最终看到的是变量i最后的值。值得注意的是,闭包存储的是其外部变量的引用而不是值。

所以,所有由wrapElements函数创建的闭包都引用在循环之前创建的变量i的同一个共享“槽”。由于每次循环迭代都递增变量i直到运行到数组结束,因此,这时候其实当我们调用其中任何一个闭包时,它都会查找数组的索引5并返回undefined值。

请注意,即使我们把var声明置于for循环的头部,wrapElements函数的表现也完全一样。


 

这个版本看起来更具欺骗性,因为var声明出现在了循环体中。但一如既往,变量声明会被提升到循环的上方。再一次,变量i只被分配了一个“槽”。

解决的办法是通过创建一个嵌套函数并立即调用它来强制创建一个局部作用域。


 

这种技术被称为立即调用的函数表达式,或IIFE(发音为“iffy”)。它是一种不可或缺的解决JavaScript缺少块级作用域的方法。另一种变种是将作为形参的局部变量绑定到IIFE并将其值作为实参传入。

 

然而,使用IIFE来创建局部作用域要小心,因为在函数中包裹代码块可能会导致代码块发生一些微妙的变化。首先,代码块不能包含任何跳出块的break语句和continue语句。因为在函数外使用break或continue是不合法的。其次,如果代码块引用了this或特别的arguments变量,IIFE将会改变它们的含义。第3章将讨论与this和arguments变量一起工作的技术。

 提示

理解绑定与赋值的区别。

闭包通过引用而不是值捕获它们的外部变量。

使用立即调用的函数表达式(IIFE)来创建局部作用域。

当心在立即调用的函数表达式中包裹代码块可能改变其行为的情形。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:第12条:理解变量声明提升
下一篇:第14条:当心命名函数表达式笨拙的作用域
相关文章
图文推荐
3.12 本章小结
3.10 添加新函数
3.9 递归
3.8 闭包
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站