javascript 闭包的理解(二)
// 定义一个User构造函数
function User(properties){
//遍历对象属性,确保它作用域正确
for(var i in properties){
(function(which){
var p = i;
//为属性创建获取器
which["get"+i] = function(){
return properties[p];
};
//为属性创建设置器
which["set"+i] = function(val){
properties[p] = val;
//return properties[p];
};
})(this);
}
} // 创建一个User实例
var user = new User({
name:"Bob",
age:44,
islive:true,
money:50000,
earn:5000,
nation:"china",
job:"web Dev"
}); user.getname(); // 返回 "Bob"
user.getage(); // 返回 "44" user.getage.call(window); // 依然返回44
user.getage.call({age: 23}); // 还是返回44
上面的这段代码(我们叫它代码段A吧)里, user.getage.call(window) 和 user.getage.call({age: 23}) 返回的结果,虽然在意料之中,但是我却并不非常清楚的知道为什么是这样。
我只是大概的知道,之所以是这个结果,肯定跟User构造函数里的闭包有关系。
我认为User构造函数里有两个闭包,所以我猜想调用user.getage的时候,就生成了2个闭包作用域。
但这只是我的猜想,事实是不是这样的呢?我想到了一个办法来验证:使用console.dir()
var getage = user.getage; console.dir(getage);
输出如下:

从输出的对象结构,可以看到这个方法它的[[Scopes]]确实有两个Closure,而且每个Closure里面有些什么东西也显示出来了。
我猜想在执行getage方法时,会先执行第一个闭包作用域,也就是Closure 0,这个闭包是由代码段A里的以下代码生成的:
which["get"+i] = function(){
return properties[p];
};
我觉得这里应该搞清楚闭包、闭包作用域、闭包包含的作用域 三个概念,否则理解起来会很蒙,搞不清楚。
闭包:就是以上代码所定义的函数which[“get”+i]。
闭包作用域:就是由以上代码生成的执行上下文空间,它就是对象结构图中的那个[[Scopes]]。
闭包包含的作用域:可以看到[[Scopes]]里面还包含了getage闭包引用的另外两个闭包的作用域里的变量:立即执行函数的作用域里的变量p 和 User函数作用域里的变量i和变量properties。
从对象结构里可以看到,闭包 Closure 0 里面存在一个变量p,因此执行闭包时,会去闭包作用域里搜索p,但搜索不到,因为p是在立即执行函数的作用域里定义的,所以会立即进入搜索Closure 0作用域的流程。
搜索Closure 0时,找到了p,并且发现p = i,此时p的定义找到了,但p等于i,所以进入搜索变量i的定义的流程。
因为变量i没有在立即执行函数里定义,所以Closure(User)被保留了下来,在立即执行函数的作用域里找不到变量i,就进入Closure(User)作用域寻找,找到了i,同时应为是立即执行函数,所以i的值一搜索到,就理解返回给p,并存入Closure 0作用域中,而Closure(User)中的i的值由于程序继续执行而变化,最后只会存入最后设置给i的值。
properties的值也是一样,在闭包作用域里找不到,就会去立即执行函数的作用域里找,找不到再去Closure(User)里找,找到了立即返回。
所以上面那段生成闭包 Closure 0 的代码执行后,返回的结果就是 properties[i],此时闭包作用域使用完毕,不再需要,可以回收,进入解析Closure(User)作用域的步骤。
然后properties[i] 被解析为 properties[“age”],然后被返回。
javascript 闭包的理解(二)的更多相关文章
- javascript闭包的理解
闭包是Javascript的一个难点,但也是一个很重要的知识点. 1.首先我们要知道变量作用域链 变量的作用域分两种:全局变量和局部变量.没有定义到任何函数中的变量为全局变量,在函数中定义的变量为局部 ...
- 我对 javascript 闭包的理解
学js的学到闭包,但是理解不深. 后来看了一下这篇文章: 地址:http://leepiao.blog.163.com/blog/static/4850313020112835355917/ 内容如下 ...
- 对JavaScript闭包的理解
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 在开始了解闭包前我们必须要先理解JavaScript的变量作用域. 一.变量的作用域无非就是两 ...
- javascript 闭包的理解(一)
过很多谈如何理解闭包的方法,但大多数文章,都是照抄或者解释<Javascript高级程序设计(第三版)>对于闭包的讲解,甚至例程都不约而同的引用高程三181页‘闭包与变量’一节的那个“返回 ...
- 关于Javascript 闭包的理解
一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话 ...
- javascript闭包的理解和实例
所谓闭包,值得是词法表示包括不必要计算的变量的函数,也就是说,该函数可以使用函数外定义的变量. 顺便提示一下: 词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通 ...
- Javascript闭包简单理解
提到闭包,想必大家都早有耳闻,下面说下我的简单理解.平时写代码.第三方框架和组件都或多或少用到了闭包.所以,了解闭包是非常必要的.呵呵... 一.什么是闭包简而言之,就是能够读取其他函数内部变量的函数 ...
- Javascript 回调函数理解---二娃子买肾机6
在Javascript中什么是回调函数,我认为简单来说就是把一个函数B作为参数传递给另一个函数A,在A函数中的一定时机调用函数B. 这里可以看出回调函数形成了一个闭包,它可以访问函数A中的活动对象. ...
- 关于Javascript闭包的理解
以下内容属个人理解,如有看不明白或漏洞之处,纯属水平不佳,还望见谅. 关于闭包,高程里的定义是:指有权访问另一个函数作用域中的变量的函数.创建闭包最常见的方法就是在一个函数的内部再创建一个函数. 这里 ...
随机推荐
- vue插件大全
一.UI组件及框架 element - 饿了么出品的Vue2的web UI工具套件 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开源 UI 组件库 Keen-UI ...
- 【LINUX】降级安装低版本GCC,G++
由于要制作crosstool,需要用到gcc 4.1.2来编译,而Ubuntu 12.04下的gcc版本是gcc 4.6.3,高版本的gcc也不是好事啊. 下面介绍gcc 4.1.2的编译安装方法: ...
- Java面向对象----多态概念,对象上下转型
概念:同一操作作用于某一类对象,可以有不同的解释,产生不同的执行结果 多态存在的三个必要条件 需要存在继承和实现关系 同样的 方法调用而执行不同操作,运行不同的代码(重写操作) 在运行时父类或者接口的 ...
- OpenCV 新手教程 之环境配置 + 图片匹配 matchTemplate
1.什么是OpenCV OpenCV的全称是:Open Source Computer Vision Library. OpenCV是一个基于(开源)发行的跨平台计算机视觉库,能够执行在Linux.W ...
- cume_dist(),允许并列名次、复制名次自动空缺,取并列后较大名次,结果如22355778……
将score按ID分组排名:cume_dist() over(partition by id order by score desc)*sum(1) over(partition by id) 将sc ...
- D - Denouncing Mafia DFS
这道题其实很简单,求k个到根的链,使得链上的节点的个数尽可能多,如果节点被计算过了,就不能再被计算了,其实我们发现,只要k>=叶子节点,那么肯定是全部,所以我们考虑所有的叶子节点,DFS到根节点 ...
- sqlserver 序号重新计算
DBCC CHECKIDENT('leshua_TradeData',NORESEED) DBCC CHECKIDENT('表名',NORESEED)
- hdu 2807 The Shortest Path(矩阵+floyd)
The Shortest Path Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- java+内存分配及变量存储位置的区别
Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详细介绍一下Java在内存分配方面的知识.一般 ...
- @noi.ac - 441@ 你天天努力
目录 @description@ @solution@ @accepted code@ @details@ @description@ 你天天努力,还是比不上小牛,因为小牛在家中套路.于是你决定去拜访 ...