浅谈JavaScript中的作用域和闭包问题

 更新时间:2015年07月07日 08:59:27   投稿:goldensun  
这篇文章主要介绍了JavaScript中的作用域和闭包问题,是JS入门学习中的基础知识,需要的朋友可以参考下

JavaScript的作用域以函数为界,不同的函数拥有相对独立的作用域。函数内部可以声明和访问全局变量,也可以声明局部变量(使用var关键字,函数的参数也是局部变量),但函数外部无法访问内部的局部变量:

function test() {
var a = 0; // 局部变量
b = 1; // 全局变量
}
a = ?, b = ? // a为undefined,b为1

同名的局部变量会覆盖全局变量,但本质上它们是两个独立的变量,一方发生变化不会影响另一方:

a = 5; // 函数外a的值为5
function test() {
var a = 4; // 函数内a的值为4
}();
a = ? // 函数外a的值仍为5,不受函数影响

一般而言,函数结束后,对函数内部变量的引用全部结束,函数内的局部变量将被回收,函数的执行环境将被清空,但是,如果以内部函数作为函数的返回结果,情况就会发生变化:

function test(i) {
var b = i * i;
return function() {
return b--;
};
}
var a = test(8);
a(); // 返回值为64, 内部变量b为63
a(); // 返回值为63, 内部变量b为62

当以内部函数作为返回值时,因为函数结束后内部变量的引用并未结束,所以函数的局部变量无法回收,函数的执行环境被保留下来,因而形成了闭包效果,可以通过该引用访问本该被回收的内部变量。
闭包还使得函数的局部变量成为“私有”变量,只能通过返回的内部函数访问,而无法通过其他任何手段去改变。
因此,闭包可用于维持局部变量和保护变量。
不使用闭包的情况:

var a = []; // 假设a中包含5个元素
for (var i = 0, m = a.length; i < m; i++) {
a[i].onclick = function(e) {
return 'No. ' + i;
};
}
// 点击任何一个元素,返回值都是“No. 5”,因为i最后的值为5
使用闭包的情况:
function test(i) {
return function(e) {
return 'No. ' + i;
};
}
var a = []; // 假设a中包含5个元素
for (var i = 0, m = a.length; i < m; i++) {
a[i].onclick = test(i);
}
// 使用闭包维持局部变量,点击元素返回No. 0 ~ No. 4

闭包带来便利的同时,也会带来一些弊端:
1、程序复杂度增加,理解更加困难
2、干扰正常的垃圾回收,复杂的闭包还可能导致内存无法回收而崩溃
3、庞大的闭包往往伴随着性能问题
因此,闭包宜精简小巧,而不宜庞大复杂,同时应避免大规模的使用闭包。闭包的出现,本身是语言的一个bug,但是因为它独特的功能而保留下来。它是一个辅助手段,而不是主要功能。

相关文章

  • JavaScript入门教程(12) js对象化编程

    JavaScript入门教程(12) js对象化编程

    关于对象化编程的语句 现在我们有实力学习以下关于对象化编程,但其实属于上一章的内容了。
    2009-01-01
  • 学习JavaScript的最佳方法分享

    学习JavaScript的最佳方法分享

    你为学习JavaScript 制定的蓝图、路线、行动计划!你不必担心找不到最好的资源,先整理些不好的资源,再确定下一步该学什么。遵循它,一步一步来
    2011-10-10
  • JavaScript:Array类型全面解析

    JavaScript:Array类型全面解析

    下面小编就为大家带来一篇JavaScript:Array类型全面解析。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • 深入解析contentWindow, contentDocument

    深入解析contentWindow, contentDocument

    没有永恒的技术只有需求,没有好说的客户只有无奈的开发者,如果iframe的出现是一个错误的话,iframe里边在来一个iframe那是错上加错,神话没有在远古的尘嚣中消失,却在怀具的今天不断上演
    2013-07-07
  • 一篇文章带你了解JavaScript的包装类型

    一篇文章带你了解JavaScript的包装类型

    这篇文章主要为大家详细介绍了JavaScript的包装类型,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • 服务端 VBScript 与 JScript 几个相同特性的写法 By shawl.qiu

    服务端 VBScript 与 JScript 几个相同特性的写法 By shawl.qiu

    服务端 VBScript 与 JScript 几个相同特性的写法 By shawl.qiu...
    2007-03-03
  • 深入理解js中this的用法

    深入理解js中this的用法

    下面小编就为大家带来一篇深入理解js中this的用法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • javascript 学习之旅 (1)

    javascript 学习之旅 (1)

    最近在看《JavaScript DOM 编程艺术》, 在此做下笔记。
    2009-02-02
  • javaScript获取对象中非空的属性实现方法详解

    javaScript获取对象中非空的属性实现方法详解

    这篇文章主要为大家介绍了javaScript获取对象中非空的属性实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 详解javascript函数写法大全

    详解javascript函数写法大全

    这篇文章主要介绍了javascript函数写法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论