深入解析JavaScript的闭包机制

 更新时间:2015年10月20日 17:33:47   投稿:goldensun  
这篇文章主要介绍了JavaScript的闭包机制,针对内嵌函数的变量访问等问题分析了JS的闭包,需要的朋友可以参考下

JavaScript 变量可以是局部变量或全局变量。
私有变量可以用到闭包。
全局变量
函数可以访问是有函数内部定义的变量,如:
实例

function myFunction() {
  var a = 4;
  return a * a;
}


函数也可以访问函数外部定义的变量,如:
实例

var a = 4;
function myFunction() {
  return a * a;
}

后面一个实例中, a 是一个 全局 变量。
在web页面中全局变量属于 window 对象。
全局变量可应用于页面上的所有脚本。
在第一个实例中, a 是一个 局部 变量。
局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。
全局和局部变量即便名称相同,它们也是两个不同的变量。修改其中一个,不会影响另一个的值。
Note 
变量声明是如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。

变量生命周期
全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。
而在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用。
计数器困境
设想下如果你想统计一些数值,且该计数器在所有函数中都是可用的。
你可以使用全局变量,函数设置计数器递增:
实例

var counter = 0;

function add() {
  counter += 1;
}

add();
add();
add();

// 计数器现在为 3

计数器数值在执行 add() 函数时发生变化。
但问题来了,页面上的任何脚本都能改变计数器,即便没有调用 add() 函数。
如果我在函数内声明计数器,如果没有调用函数将无法修改计数器的值:
实例

function add() {
  var counter = 0;
  counter += 1;
}

add();
add();
add();

// 本意是想输出 3, 但事与愿违,输出的都是 1 !

以上代码将无法正确输出,每次我调用 add() 函数,计数器都会设置为 1。
JavaScript 内嵌函数可以解决该问题。
JavaScript 内嵌函数
所有函数都能访问全局变量。 
实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。
JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。
该实例中,内嵌函数 plus() 可以访问父函数的 counter 变量:
实例

function add() {
  var counter = 0;
  function plus() {counter += 1;}
  plus();  
  return counter; 
}

如果我们能在外部访问 plus() 函数,这样就能解决计数器的困境。
我们同样需要确保 counter = 0 只执行一次。
我们需要闭包。
JavaScript 闭包
还记得函数自我调用吗?该函数会做什么?
实例

var add = (function () {
  var counter = 0;
  return function () {return counter += 1;}
})();

add();
add();
add();

// 计数器为 3

实例解析
变量 add 指定了函数自我调用的返回字值。
自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。
add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。
这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。
计数器受匿名函数的作用域保护,只能通过 add 方法修改。

Note 
闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。

相关文章

  • 详解JavaScript闭包问题

    详解JavaScript闭包问题

    这篇文章主要介绍了详解JavaScript闭包问题,通过案例一步步进行讲解了该项技术问题,讲述了变量的作用域,闭包的概念和作用,需要的朋友可以参考下
    2021-06-06
  • js代码实现随机颜色的小方块

    js代码实现随机颜色的小方块

    这篇文章主要用js代码实现颜色随机的小方块,需要的朋友可以参考下
    2015-07-07
  • JS Attribute属性操作详解

    JS Attribute属性操作详解

    下面小编就为大家带来一篇JS Attribute属性操作详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • JavaScript 学习笔记之数据类型

    JavaScript 学习笔记之数据类型

    javascript数据类型非常简单,仅仅包含undefined、null、string、Boolean、number以及object,今天我们就针对这几个数据类型,一一进行讲解,方便大家理解记忆
    2015-01-01
  • ASP.NET实现Repeater控件的数据绑定

    ASP.NET实现Repeater控件的数据绑定

    这篇文章介绍了ASP.NET实现Repeater控件数据绑定的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • 举例讲解JavaScript中关于对象操作的相关知识

    举例讲解JavaScript中关于对象操作的相关知识

    这篇文章主要介绍了举例讲解javaScript中关于对象操作的相关知识,"一切皆对象"是学习JS过程中经常可以见到的一句话,本文便用一些小例子来讲解JS中的对象操作,需要的朋友可以参考下
    2015-11-11
  • 深入document.write()与HTML4.01的非成对标签的详解

    深入document.write()与HTML4.01的非成对标签的详解

    本篇文章对document.write()与HTML4.01的非成对标签进行了详细的分析介绍。需要的朋友参考下
    2013-05-05
  • 让我们一起来学习一下什么是javascript的闭包

    让我们一起来学习一下什么是javascript的闭包

    这篇文章主要为大家详细介绍了javascript的闭包,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • JavaScript中的getDay()方法使用详解

    JavaScript中的getDay()方法使用详解

    这篇文章主要介绍了JavaScript中的getDay()方法使用详解,是JS入门学习中的基础知识,需要的朋友可以参考下
    2015-06-06
  • nodeType属性返回被选节点的节点类型介绍

    nodeType属性返回被选节点的节点类型介绍

    这篇文章主要介绍了nodeType属性返回被选节点的节点类型。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-11-11

最新评论