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)实现的.但 ...
随机推荐
- web设计经验<九>教你测试手机网页的5大方法
我们知道手机浏览器的使用量每天都在增长,根据StatCounter的统计数据,手机和平板的使用量约占30%的网络流量,这意味着消费者耗费在移动版网页上的时间比以往任何时候都高.可即使具备诸如移动端优先 ...
- php按条件查询的数据分页显示,点击下一页时又列出全部数据的解决办法
其实很简单,只要把表单提交方式改为get方式就行了,然后调用分页函数: function getpage(&$m,$where,$pagesize=10){ $m1=clone $m;//浅复 ...
- Linux系统负载排查
参考 http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html 在Linux系统中,我们一般使用uptime命 ...
- MyBatis学习笔记(二) 关联关系
首先给大家推荐几个网页: http://blog.csdn.net/isea533/article/category/2092001 没事看看 - MyBatis工具:www.mybatis.tk h ...
- C#_观察者模式
假设有一个软件公司,每当有新产品推出,就把信息通知到一些客户. 把通知这个动作抽象成一个接口. public interface IService { void Notif(); } 客户如果想获得通 ...
- php中mysql数据库异步查询实现
问题 通常一个web应用的性能瓶颈在数据库.因为,通常情况下php中mysql查询是串行的.也就是说,如果指定两条sql语句时,第二条sql语句会等到第一条sql语句执行完毕再去执行.这个时候,如果执 ...
- JavaScript设计模式与开发实践 - 策略模式
引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
- C++ Primer 第二章 引用 指针 const限定符
1.引用: 为对象起了另外一个名字,引用类型引用另外一种类型,通过将声明符写成&d的形式来定义引用类型,其中d也就是声明的变量名(声明符就是变量名). PS:1.通过图片中编译所提示的报错信息 ...
- Windows7隐藏字体
今天突然发现字体Times New Roman消失了,如下图所示: 图1.1 不仅仅Times New Roman,还有System.MS Sans Serif--这些熟悉的字体都消失了,不能选用了! ...
- Windows菜单
目录 第1章 Windows菜单 1 1.1 窗口菜单和弹出菜单 1 1.2 使用SetMenu 2 1.3 使用TrackPopupMenu 4 第1章 Windows菜单 ...