L1 - 闭包和原型链
先来一炮尝尝:
var i = 10;
function myFunc(){
var i = 20;
function innerFunc(){
alert(i);
}
return innerFunc;
}
var func = myFunc();
func();
此栗为什么弹出20,而不是10?为什么定义在 myFunc 内部的 innerFunc 返回了以后,还能访问到 myFunc 内部的变量 i ?
这是因为在 innerFunc 返回了以后,仍然保留着函数运行的实例、执行环境和作用域链等等,并在 myFunc 调用之后没有将函数实例丢弃,因此在调用 innerfunc 的时候能够引用到 myfunc 中声明的 i ,这就是闭包的特性,其实上面的栗子就是一个闭包。
作用域链是一个链状的数据结构。作用域就是对上下文数据的描述。闭包和作用域链是紧密联系的,函数实例执行时的闭包是构成作用域链的基本元素。javascript代码在执行前会进行语法分析(详见L1 - 运行机制),在语法分析阶段,会记录全局环境中的变量声明和函数定义,构造函数的调用对象(也叫 active object、活动对象)和在全局环境下的作用域链。
《javascript权威指南》(第四版)对“调用对象”做出了三点说明:
1、对象属性和变量没有本质区别
2、全局变量其实是“全局对象(global object)“的属性
3、局部变量其实是”调用对象(call object)“的属性
为了解释上述话题,《javascript权威指南》引入了”javascript执行环境(执行上下文、execution context)的概念“。这其中所说到的“全局对象(global object)“和”调用对象(call object)“其实都是指下图中的 ScriptObject 结构。

上图是《JavaScript语言精髓和编程实践》中对闭包相关元素的内部数据结构的描述,其中的 ScriptObject 是对调用对象的一种描述。 ScriptObject 在语法分析阶段就已经构造好了,其中的 varDecls 保存着函数中的变量声明,funDecls保存着内部的函数声明。
在上篇《执行机制》中已经讲过,在语法分析阶段,varDecls 中保存着在函数中用var进行显示声明的局部变量,并且其值默认为 undefined ;而发现有函数定义时,除了记录函数声明,还会创建一个函数对象,并把当前的作用域链赋值给此函数对象的 [[scope]] 属性(这个属性是javascript引擎内部维护的,但Firefox可通过私有属性parent访问它)。这就是为什么在《javascript权威指南》中提到”javascript中的函数运行在它们被定义的作用域中,而不是运行在它们被执行的作用域中“。
再来一炮:(未完待续)
L1 - 闭包和原型链的更多相关文章
- jquery学习笔记---闭包,原型链,this关键字
网上的资料很多,关于闭包,原型链,面向对象之内的.本人也有一点自己的总结. 关于this: this 的值取决于 function 被调用的方式,一共有四种, 如果一个 function 是一个对象的 ...
- 几句话就能让你理解:this、闭包、原型链
以下是个人对这三个老大难的总结(最近一直在学习原生JS,翻了不少书,不少文档,虽然还是新手,但我会继续坚持走我自己的路) 原型链 所有对象都是基于Object.prototype,Object.pro ...
- JAVASCRIPT闭包以及原型链
方法内部还有个方法,实例化父方法后,再次调用父方法,可以运行父方法内部的子方法,这样的程序就叫做闭包 DEMO如下: //function outerFn() { // var outerVar = ...
- 在学习java之余,js的使用精髓-闭包和原型链
这里分享下廖雪峰官网写的js教程,内容写的比较实用,易懂,其中简介的原型链和闭包的知识,小伙伴们一起上呀,畅游在知识的海洋中: 地址:https://www.liaoxuefeng.com/wiki/ ...
- js学习笔记之自调用函数、闭包、原型链
自调用函数 var name = 'world!'; // console.log(typeof name) (function () { console.log(this.name, name, ...
- Vue之JavaScript基础(闭包与原型链)
闭包 定义:能够访问另一个函数作用域的变量的函数. 作用:可以通过闭包,设计私有变量及方法 实例: function outer() { var a = '变量1' var inner = funct ...
- js闭包和原型链好文
http://www.cnblogs.com/wangfupeng1988/p/3977924.html
- es6之后,真的不需要知道原型链了吗?
3月份几乎每天都能看到面试的人从我身边经过,前段时间同事聊面试话题提到了原型链,顿时激起了我在开始学习前端时很多心酸的回忆.第一次接触js的面向对象思想是在读<js高程设计>(红宝书)的时 ...
- Js中关于构造函数,原型,原型链深入理解
在 ES6之前,在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但 ...
随机推荐
- 图文解说 Dijkstra.
Dijkstra 太多文章了,有些简练,有些一笔带过.自己还是花了些时间才明白,刚脆自己写个图文说明的,希望能让还没明白的,尽快清楚. 问题:求某点到图中其他所有点的最短路径(权值和最小) Dijks ...
- maven setting.xml配置说明
文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${use ...
- (一)使用springAPI以及自定义类 实现AOP-aop编程
Spring的另一个重要思想是AOP,面向切面的编程,它提供了一种机制,可以在执行业务前后执行另外的代码,Servlet中的Filter就是一种AOP思想的体现,下面通过一个例子来感受一下. 假设我们 ...
- ListFragment
ListFragment http://developer.android.com/reference/android/app/ListFragment.html extends Fragment C ...
- ORA-12705: Cannot access NLS data files or invalid environment specified
ASM实例无法启动 [grid@data ~]$ sqlplus / as sysasm SQL*Plus: Release 11.2.0.4.0 Production on Fri Sep 11 0 ...
- UEditor 之查询当前编辑区域的状态是源码模式还是可视化模式
在使用百度的编辑器的时候,遇到了这样的一个问题: 解决方法是 使用了两个命令:
- Mvc4_传值取值应用
Mvc路由运行机制: 首先,Web 浏览器向服务器发送一条URL 请求,如http://HostName/ControllerName/ActionName/Parameters. 其次,请求被A ...
- Redis常用的基本命令整理
SET key value [EX seconds] [PX milliseconds] [NX|XX] 设置缓存 K-V,如果 key 已经存在,则重写 EX seconds -- 设置过期时间, ...
- phalcon count统计
单表count: //How many robots are there? $number = Robots::count(); echo "There are ", $numbe ...
- 不能使用tpcc-mysql测试OneProxy
因为Proxy类的中间件不适合实现prepared statement,所以无法测试,导致我们无法使用标准的测试工具去发布OneProxy的测试结果