1. 闭包是一个函数,这个函数有权访问另一个函数作用域中的变量,创建闭包最常见的方式,就是在函数内部创建函数。要想彻底搞清其中细节,必须从函数从创建到调用的时候都发生了什么入手

2. 函数第一次被调用,创建一个执行环境,和相应的作用域链

3. 作用域链赋值给一个特殊的内部属性Scope

4. 使用this,arguments和其他命名参数的值初始化函数的变量对象

5. 在作用域链中,内部函数的活动对象处于第一位,外部函数的活动对象始终处于第二位……直至全局执行环境

6. 执行函数时,为读取写入变量的值,需要在作用域链中查找变量

function compare(a  ,b){
if(a<b){
return -1;
}else if(a>b){
return 1;
}else{
return 0;
}
}
var result = compare(5,10); // -1 1. 第一次调用compare()函数时,会创建一个活动对象,包括{this,arguments ,a,b}
2. 全局执行环境的变量对象{compare , result, this},在compare()的作用域链中处于第二位的

7. 每一个执行环境都有一个用来存放变量的对象——变量对象

  1.  全局环境中的变量对象始终存在

  2.  compare函数的局部环境的变量对象,只在函数执行过程中存在

8.  在创建compare函数时,先创建一个作用域链,这个作用域链预先就包含了全局变量对象

9. 作用域链保存在compare函数内部的Scope属性中

10. 调用compare函数时,会为函数创建一个执行环境,compare函数的局部变量对象被创建并放到作用域链的前端。

11. 所以,作用域链本质上是一个指向变量对象的指针列表,只引用但不实际包含变量对象

  1. Scope[{this,arguments ,a,b} , {compare , result, this}]

  2. compare函数在访问一个变量时,先从scope中第一个元素开始搜索,一个一个往后找

  3. 函数执行完毕后,局部变量对象被销毁,内存中仅存全局变量对象


1. 存在闭包就不一样了

2. 在函数内部定义的函数(子函数)会将外部函数(父函数)的变量对象添加到它(子函数)的作用域链中

function createCompareFunction(propName){
return function(obj1 , obj2){
var a = obj1[propName];
var b = obj2[propName]; if(a<b){
return -1;
}else if(a>b){
return 1;
}else{
return 0;
}
}
} var compare = createCompareFunction('name');
var result = compare({name:"Nico"} , {name:"Greg"});//true 1. 在内部的匿名函数的作用域链中,实际上包含外部函数的变量对象
2. 这个内部的匿名函数被return到外部后,这个匿名函数它的作用域链被初始化了
3. 包含createCompareFunction函数的变量对象以及全局变量对象
4. 所以,匿名函数可以访问createCompareFunction函数中所有的变量
5. 更为重要的是,createCompareFunction函数执行完毕被销毁后,其变量对象还有一份保存在匿名函数中,所以仍可以访问其内部的变量

JavaScript闭包底层解析的更多相关文章

  1. Javascript闭包深入解析及实现方法

    1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点:1. 作为一个函数变量的一个引用,当函数返回时 ...

  2. JavaScript闭包深入解析

    for (var i=1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } --上面这段 ...

  3. JavaScript闭包的底层运行机制

    转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...

  4. javascript闭包学习

    (function(){})()===>>>>函数会被立即执行function(){}是一个函数用括号包起来表示是函数表达式再加()表示函数自执行  如何理解闭包?1.定义和用 ...

  5. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  6. javascript闭包和作用域链

    最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...

  7. Javascript闭包的一些研究

    原文:Javascript闭包的一些研究 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助. 程序1 var f = (function( ...

  8. javascript闭包—围观大神如何解释闭包

    闭包的概念已经出来很长时间了,网上资源一大把,本着拿来主意的方法来看看. 这一篇文章 学习Javascript闭包(Closure) 是大神阮一峰的博文,作者循序渐进,讲的很透彻.下面一一剖析. 1. ...

  9. javascript 闭包内部机制

    在初学JavaScript函数式编程的时候,经常会出现令人出乎意料的结果,而原因,大都是由于不理解JavaScript闭包引起的:理解JavaScript的闭包,可以从JavaScript的闭包内部机 ...

随机推荐

  1. table tr分离并加圆角和阴影

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. algorithms中计算时间的渐近表示

    1.大写Ο符号大写Ο符号给出了函数f的一个上限. 定义[大写Ο符号]:f(n)=Ο(g(n)),当且仅当存在正的常数c和n0,使得对于所有的n≥n0,有 f(n)≤c*g(n) 上述定义表明,函数f至 ...

  3. oracle中的 exists 和 in 的效率问题

    1) select * from T1 where exists(select * from T2 where T1.a=T2.a) ; T1数据量小而T2数据量非常大时,T1<<T2 时 ...

  4. PHP 点滴疑惑

    在数据库中,字段为NULL,可以使用empty()进行判断 <?php $CONFIG['hostname'] = 'localhost'; $CONFIG['username'] = 'roo ...

  5. Java事务处理总结

    http://lavasoft.blog.51cto.com/62575/53815/ 一.什么是Java事务   通常的观念认为,事务仅与数据库相关.   事务必须服从ISO/IEC所制定的ACID ...

  6. 如何在Windows系统上用抓包软件Wireshark截获iPhone等网络通讯数据

    http://www.jb51.net/os/windows/189090.html 今天给大家介绍一种如何在Windows操作系统上使用著名的抓包工具软件Wireshark来截获iPhone.iPa ...

  7. CSS FIXED porn javhd

    CSS position property - W3Schools W3Schools › cssref › pr_class_position Definition and Usage. The p ...

  8. eclipse导入包的快捷键

    在Eclipse里,写一个没有导入相应包的类名(这个类名已经完全写全,比如LayoutManager), 可以用ctrl+shift+M/Ctrl+Shift+o/Ctrl+1导入相应的包. 其中Ct ...

  9. dorado需要的包

    创建dorado示例中心项目WEB-INF下的lib里的包有很多,包括连接数据库的完整的包,新建的项目,可以直接从这里面拷贝包. 当然如果需要连接mySql数据库,还需要手动导入mySql的包.

  10. (转)RPC原理详解

    转自:http://www.open-open.com/lib/view/open1425797146897.html RPC功能目标 RPC的主要功能目标是让构建分布式计算(应用)更加容易,在提供强 ...