javascript闭包的理解和实例
所谓闭包,值得是词法表示包括不必要计算的变量的函数,也就是说,该函数可以使用函数外定义的变量。
顺便提示一下:
词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析就能确定,因此词法作用域也叫做静态作用域。 with和eval除外,所以只能说JS的作用域机制非常接近词法作用域(Lexical scope)。
下面是一个简单的使用全局变量的闭包实例:
2 function disWord(){
3 alert(sWord);
4 }
5 disWord();
解析:脚本载入到内存的时候,disWord并没有计算sWord的值,而是函数disWord调用的时候执行了sWord的计算。
下面是函数中定义另一个函数的闭包实例:
2 function add(num1,num2){
3 function doAdd(){return num1+num2+iNum;}
4 return doAdd();
5 }
解析:内部函数doAdd是个闭包,它将获取传入参数num1,num2和全局变量iNum的值,doAdd不接受参数,add最后一步调用doAdd,请两个参数和全局变量求和返回,可以看得出doAdd使用的值是在执行环境中获得的。
下面是在网上找的几个例子,理解词法作用域和闭包
1、案例一
2 function a(i) {
3 var i;
4 alert(i);
5 };
6 a(10);
疑问:上面的代码会输出什么呢?
答案:10。
具体执行过程
- a 函数有一个形参 i,调用 a 函数时传入实参 10,形参 i=10
- 接着定义一个同名的局部变量 i,未赋值
- alert 输出 10
思考:局部变量 i 和形参 i 是同一个存储空间吗?
2、案例二
2 function a(i) {
3 alert(i);
4 alert(arguments[0]); //arguments[0]应该就是形参 i
5 var i = 2;
6 alert(i);
7 alert(arguments[0]);
8 };
9 a(10);
疑问:上面的代码又会输出什么呢?
答案:10,10,2,2
具体执行过程
- 函数有一个形参i,调用 a 函数时传入实参 10,形参 i=10
- 第一个 alert 把形参 i 的值 10 输出
- 第二个 alert 把 arguments[0] 输出,应该也是 i
- 接着定义个局部变量 i 并赋值为2,这时候局部变量 i=2
- 第三个 alert 就把局部变量 i 的值 2 输出
- 第四个alert再次把 argumentsa[0] 输出
思考:这里能说明局部变量 i 和形参 i 的值相同吗?
3、案例三
2 function a(i) {
3 var i = i;
4 alert(i);
5 };
6 a(10)
疑问:上面的代码又又会输出什么呢?
答案:10
具体执行过程
- 第一句声明一个与形参 i 同名的局部变量 i,根据结果我们知道,后一个 i 是指向了
- 形参 i,所以这里就等于把形参 i 的值 10 赋了局部变量 i
- 第二个 alert 当然就输出 10
思考:结合案列二,这里基本能说明局部变量 i 和形参 i 指向了同一个存储地址!
4、案例四
2 var i=10;
3 function a() {
4 alert(i);
5 var i = 2;
6 alert(i);
7 };
8 a();
疑问:上面的代码又会输出什么呢?
答案:undefined, 2
具体执行过程
- 第一个alert输出undefined
- 第二个alert输出 2
思考:到底怎么回事儿?
看到上面的几个例子,你可能会想到底是怎么执行的呢?执行的细节又是怎么样的呢? JS 引擎的工作方式是怎样的呢?
解析过程
1、执行顺序
编译型语言,编译步骤分为:词法分析、语法分析、语义检查、代码优化和字节生成。
解释型语言,通过词法分析和语法分析得到语法分析树后,就可以开始解释执行了。这里是一个简单原始的关于解析过程的原理,仅作为参考,详细的解析过程(各种JS引擎还有不同)还需要更深一步的研究
javascript的执行过程,如果一个文档流中包含多个script代码段(用script标签分隔的js代码或引入的js文件),它们的运行顺序是:
- 步骤1. 读入第一个代码段(js执行引擎并非一行一行地执行程序,而是一段一段地分析执行的)
- 步骤2. 做词法分析和语法分析,有错则报语法错误(比如括号不匹配等),并跳转到步骤5
- 步骤3. 对【var】变量和【function】定义做“预解析“(永远不会报错的,因为只解析正确的声明)
- 步骤4. 执行代码段,有错则报错(比如变量未定义)
- 步骤5. 如果还有下一个代码段,则读入下一个代码段,重复步骤2
- 步骤6. 结束
2、特殊说明
全局域(window)域下所有JS代码可以被看成是一个“匿名方法“,它会被自动执行,而此“匿名方法“内的其它方法则是在被显示调用的时候才被执行
3、关键步骤
上面的过程,我们主要是分成两个阶段
- 解析:就是通过语法分析和预解析构造合法的语法分析树。
- 执行:执行具体的某个function,JS引擎在执行每个函数实例时,都会创建一个执行环境(ExecutionContext)和活动对象(activeObject)(它们属于宿主对象,与函数实例的生命周期保持一致)
在这里有更详细的实例分析资料:http://www.alixixi.com/web/a/2010062560089.shtml
javascript闭包的理解和实例的更多相关文章
- javascript闭包的理解
闭包是Javascript的一个难点,但也是一个很重要的知识点. 1.首先我们要知道变量作用域链 变量的作用域分两种:全局变量和局部变量.没有定义到任何函数中的变量为全局变量,在函数中定义的变量为局部 ...
- 我对 javascript 闭包的理解
学js的学到闭包,但是理解不深. 后来看了一下这篇文章: 地址:http://leepiao.blog.163.com/blog/static/4850313020112835355917/ 内容如下 ...
- 对JavaScript闭包的理解
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 在开始了解闭包前我们必须要先理解JavaScript的变量作用域. 一.变量的作用域无非就是两 ...
- javascript 闭包的理解(一)
过很多谈如何理解闭包的方法,但大多数文章,都是照抄或者解释<Javascript高级程序设计(第三版)>对于闭包的讲解,甚至例程都不约而同的引用高程三181页‘闭包与变量’一节的那个“返回 ...
- 关于Javascript 闭包的理解
一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话 ...
- javascript 闭包的理解(二)
// 定义一个User构造函数 function User(properties){ //遍历对象属性,确保它作用域正确 for(var i in properties){ (function(whi ...
- 关于Javascript闭包的理解
以下内容属个人理解,如有看不明白或漏洞之处,纯属水平不佳,还望见谅. 关于闭包,高程里的定义是:指有权访问另一个函数作用域中的变量的函数.创建闭包最常见的方法就是在一个函数的内部再创建一个函数. 这里 ...
- Javascript闭包简单理解
提到闭包,想必大家都早有耳闻,下面说下我的简单理解.平时写代码.第三方框架和组件都或多或少用到了闭包.所以,了解闭包是非常必要的.呵呵... 一.什么是闭包简而言之,就是能够读取其他函数内部变量的函数 ...
- javascript 闭包的理解
1 需要明白概念: 执行环境 变量对象,活动对象 作用域,作用域链 闭包 垃圾处理机制 闭包陷阱
随机推荐
- JavaScript九九乘法表
JavaScript九九乘法表 <script> for (var i = 1; i < 10; i++) { for (var j = 1; j <= i; j++) { d ...
- mysql查询时不区分大小写
一次偶然的机会,发现在登陆验证时,改变用户名的大小写,同样可以登录成功,这是由于,当时使用的mysql数据库对大小写不敏感,查询时总是能查询到数据.一番查找资料,给出的原因是:在创建数据库的时候,选择 ...
- Galactic Collegiate Programming Contest Gym - 101572G 模拟
#include<bits/stdc++.h> using namespace std; int n,m; struct node { int id; int slove; int pen ...
- MySQL概述及入门(一)
MySql概述及入门(一) 什么是MySQL? MySQL是当今主流的关系型数据库管理系统(记录是有行有列的数据库) , 可以与Oracle 和SQL Server 竞争 , 是最好RDBMS( ...
- ImportError: DLL load failed with error code -1073741795
Win7,python3.6,pip安装tensorflow之后报错: >>> import tensorflow Traceback (most recent call last) ...
- Spring Aop和Spring Ioc(二)
Spring IOC: DI注入集合类型: 实体类: package cn.spring.entity; import java.util.*; public class Dientity { pri ...
- Antenna Placement poj 3020
Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12104 Accepted: 595 ...
- JSP页面取不到ModelAndView里面存的值
方法1:在jsp页面上加上<%@ page isELIgnored="false" %>
- Python语法速查: 14. 测试与调优
返回目录 本篇索引 (1)测试的基本概念 (2)doctest模块 (3)unittest模块 (4)调试器和pdb模块 (5)程序探查 (6)调优与优化 (1)测试的基本概念 对程序的各个部分建立测 ...
- EasyUI笔记(一)Base基础
总结: 1)每个UI都是通过属性.事件和方法运作的 2)用JS加载时只需传入一个参数(用大括号{}包围),包含若干个键值对,之间用逗号隔开: 3)事件也是写在JS加载时的方法中,也是键值对形式,值是匿 ...