《深入理解JavaScript》——1.13 变量作用域和闭包

1.13 变量作用域和闭包

在JavaScript中,通过在变量前使用var语句声明变量:

  

你可以使用单个var语句声明和初始化多个变量:

  

但是我推荐使用单独声明每一个变量(原因参考26.4.1“语法”)。因此,我会将之前的语句重写为:

  

由于前置的缘故(参考1.13.2“变量的提升特性”),通常它的最佳实践是在一个函数的开始部分声明变量。

1.13.1 变量是函数作用域的
一个变量的作用域总是完整的函数(相对于当前块)。例如:

  

我们可以看到变量tmp并不局限于(1)行;直到函数结束它都存在。

1.13.2 变量的提升特性
所有变量声明都会被提升:声明会被移动到函数的开始处,而赋值则仍然会在原来的位置进行。例如,以下函数中的变量会被认为是在标记为(1)的这行声明的:

  

然而在程序内部,上述函数的执行过程其实是这样的:

  

1.13.3 闭包
每个函数都和它周围的变量保持着连接,哪怕它离开被创建时的作用域也是如此。例如:

  

函数从标记为(1)的这行开始被创建,在创建结束后即离开它的上下文环境,但它仍然保持着和start的连接:

  

函数以及它所连接的周围作用域中的变量即为闭包。所以,create Incrementor()的返回其实就是一个闭包。

1.13.4 IIFE模式:引入一个新的作用域
有时你会想要引入一个新的作用域,例如,防止一个变量变成全局变量。在JavaScript中,不能通过块来做,必须使用函数。不过有一种模式可以将函数当做类似块的方式来使用。这种模式被称作为IIFE(立即调用函数表达式,发音为“iffy”):

  

请务必键入以上示例(注释除外)。IIFE是一个在定义之后就被立即调用的函数表达式。在函数内部,会有一个新的作用域,以防止tmp变成全局变量。更多关于IIFE的细节,参见16.6“通过IIFE引入新的作用域”。

IIFE用例:闭包造成的无意共享
闭包会持续地保持与外部变量的连接,而这有时候并不是你想要的:

 

标记为(1)的这行返回值总是i的当前值,而并非函数被创建时的值。在循环结束之后,i的值为5,所以数组中所有的函数都返回这个数值。如果你想要标记(1)这行的函数获得当前i值的一个快照,那么你可以使用IIFE:

  

时间: 2024-08-01 08:29:32

《深入理解JavaScript》——1.13 变量作用域和闭包的相关文章

javascript 与 jquery 变量作用域差异问题

问题描述 javascript 与 jquery 变量作用域差异问题 /***javascript例子***/ function fn(){ var oo="oo"; function fnn(){ alert(oo); } fnn(); } fn(); // 结果 undefined /***jquery 例子***/ $( function(){ var oo="oo"; function fnn(){ alert(oo); } fnn(); } ) // 结果

深入理解JavaScript高级之词法作用域和作用域链_基础知识

主要内容:1.分析JavaScript的词法作用域的含义 2.解析变量的作用域链 3.变量名提升时什么 最近在传智播客讲解JavaScript的课程,有不少朋友觉得JavaScript是如此的简单,但是又如此的不知如何使用,因此我准备了一些内容给大家分享一下. 这个系列主要讲解JavaScript的高级部分的内容,包括作用域链.闭包.函数调用模式.原型以及面向对象的一些东西. 在这里不包含JavaScript的基本语法,如果需要了解基础的同学可以到http://net.itcast.cn里面去下

javascript中的变量作用域以及变量提升详细介绍_javascript技巧

变量作用域"一个变量的作用域表示这个变量存在的上下文.它指定了你可以访问哪些变量以及你是否有权限访问某个变量." 变量作用域分为局部作用域和全局作用域. 局部变量(处于函数级别的作用域)不像其他对面对象的编程语言(比方说C++,Java等等),javascript没有块级作用域(被花括号包围的):当是,javascript有拥有函数级别的作用域,也就是说,在一个函数内定义的变量只能在函数内部访问或者这个函数内部的函数访问(闭包除外,这个我们过几天再写个专题). 函数级别作用域的一个例子

深入解析JavaScript中的变量作用域_javascript技巧

在学习JavaScript的变量作用域之前,我们应当明确几点: •JavaScript的变量作用域是基于其特有的作用域链的. •JavaScript没有块级作用域. •函数中声明的变量在整个函数中都有定义. 1.JavaScript的作用域链首先看下下面这段代码: 复制代码 代码如下: <script type="text/javascript"> var rain = 1; function rainman(){ var man = 2; function inner()

深入理解JavaScript系列(13) This? Yes,this!_javascript技巧

介绍 在这篇文章里,我们将讨论跟执行上下文直接相关的更多细节.讨论的主题就是this关键字.实践证明,这个主题很难,在不同执行上下文中this的确定经常会发生问题. 许多程序员习惯的认为,在程序语言中,this关键字与面向对象程序开发紧密相关,其完全指向由构造器新创建的对象.在ECMAScript规范中也是这样实现的,但正如我们将看到那样,在ECMAScript中,this并不限于只用来指向新创建的对象. 英文翻译: Dmitry A. Soshnikov在Stoyan Stefanov的帮助下

深入理解JavaScript系列(12) 变量对象(Variable Object)_javascript技巧

JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,但是解释器是如何并且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候究竟发生了什么? 原始发布:Dmitry A. Soshnikov 发布时间:2009-06-27 俄文地址:http://dmitrysoshnikov.com/ecmascript/ru-chapter-2-variable-object/ 英文翻译:Dmitry A. Soshnikov 发布时间:2010-03-15 英文地址:http

JavaScript 变量作用域及闭包第1/2页_javascript技巧

实例一: 复制代码 代码如下: <script type="text/javascript"> var i = 1; // 弹出内容为 1 true 的提示框 alert(window.i + ' ' + (window.i == i)); </script> 分析: 在全局定义的变量其实就是 window 对象的属性. 上面的例子可以看到,我们定义全局变量的同时,window 对象会产生一个相应的属性,如何让我们的代码避免产生这个属性呢,看下面的例子. 实例二

深入理解javascript闭包

变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域 变量的作用域无非就是两种:全局变量和局部变量 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 var n=999; function f1(){ alert(++n); } f1(); // 1000 另一方面,在函数外部无法读取函数内的局部变量 function f1(){ var n=999; } alert(++n); // error 这里有一个地方需要注意,函数内部声明变量的时候,一定要

深入理解JavaScript系列(转载)

深入理解JavaScript系列 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 深入理解JavaScript系列(2):揭秘命名函数表达式 深入理解JavaScript系列(3):全面解析Module模式 深入理解JavaScript系列(4):立即调用的函数表达式 深入理解JavaScript系列(5):强大的原型和原型链 深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP 深入理解JavaScript系列(7):S.O.