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闭包的理解
以下内容属个人理解,如有看不明白或漏洞之处,纯属水平不佳,还望见谅. 关于闭包,高程里的定义是:指有权访问另一个函数作用域中的变量的函数.创建闭包最常见的方法就是在一个函数的内部再创建一个函数. 这里 ...
随机推荐
- mySQL start service失败终极解决办法
start service失败 原因是电脑没删干净.具体1.先卸载2.计算机“搜索”所有MySQL文件 注意隐藏文件也可以搜索出来全部删除.3.清除注册表MySQL及子项.4.防火墙的问题 不要勾 ...
- Java练习 SDUT-2585_机器人II
机器人II Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 自从xiao_wu发明了只能向左转与向右转的机器人以后,热血 ...
- 终端安装opencv
安装 要想在 notebook 中安装和使用 OpenCV,请打开终端窗口(也被称为 Windows 用户的命令提示符窗口),并使用以下命令通过 conda 安装最新版本 (v3): conda in ...
- Laravel 上传excel,读取并写入数据库 (实现自动建表、存记录值
<?php namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminat ...
- HTML5--语法
一.标记方法 1.内容类型(ContentType)还是.text/html 2.声明:<!DOCTYPE html SYSTEM “about:legacy-compat”> 3.字符编 ...
- OP_REQUIRES failed at conv_ops.cc:386 : Resource exhausted: OOM when allocating tensor with shape..
tensorflow-gpu验证准确率是报错如上: 解决办法: 1. 加入os.environ['CUDA_VISIBLE_DEVICES']='2' 强制使用CPU验证-----慢 2.'batch ...
- lualatex+Beamer生成ppt
直接放模板代码 \documentclass{beamer} % There are many different themes available for Beamer. A comprehensi ...
- 【原生JS】自动渐变轮播
渐变主要是通过CSS3的动画实现. 只需给css中添加transtion动画时间加上JS设置指定图片透明度显示与消失即可实现渐变过程. 效果图: HTML: <!DOCTYPE html> ...
- Python--day48--今日内容
- tensorflow学习笔记(二十五):ConfigProto&GPU
tensorflow ConfigPrototf.ConfigProto一般用在创建session的时候.用来对session进行参数配置 with tf.Session(config = tf.Co ...