Javascript本质第二篇:执行上下文
在上一篇文章《Javascript本质第一篇:核心概念》中,对Javascript执行上下文做了解释,但是这些都是基于Javascript标准中对执行上下文的定义,也就是说理论上的东西,本文将在Google Chrome中通过实际代码来展示Javascript的执行上下文。
1. Javascritp运行时内存监控
Google Chrome的开发人员工具包含了Javascript性能监控工具,通过这个工具可以查看Javascript运行时内存占用情况、监控CPU消耗、查找内存泄漏等。
F12打开Chrome的开发人员工具,点击“Profiles”选项卡,选择“Take Heap Snapshot”,点击“Take Snapshot”按钮(或者点击下面黑色的实心圆)就可以拍摄一个当前内存的快照。
在快照中可以浏览当前Javascript运行时中包含的所有对象的信息和对象之间的引用关系,这些对象包括用户创建的对象和系统创建的对象。
由于一个快照中包含的对象数量往往非常大,多数都是页面初始化时创建的页面对象和用户不可访问的系统对象,不便于查找。为此,可以拍摄两个快照,Chrome能够计算出在两个快照之间创建的对象,通过分析新增对象,可以直观的看到代码运行时内存分配和占用情况。
2. 执行上下文
创建一段包含两级嵌套执行上下文的演示代码 :
fun = (function () {
var a = (Math.random() * 10000).toFixed();
return (function () {
var b = (Math.random() * 10000).toFixed();
var f = function () {
var c = (Math.random() * 10000).toFixed();
return a + " - " + b + " - " + c;
};
return f;
})
})();
a = fun();
b = fun();
先在console先运行一遍这段代码,拍摄一个内存快照Snapshot 1。
再在console运行一遍这段代码,拍摄一个内存快照Snapshot 2。
(如果直接上来拍摄内存快照Snapshot 1,运行代码再拍摄Snapshot 2,由于代码第一次运行,会产生大量系统对象,不便于对象查找。)
在Profiles标签页的下方选择Objects allocated between Snapshots 1 and 2。
这时对象窗口就按构造函数分类列出了所有对象。
找到(closure)行,展开,查找被高亮的三行,这三行就对应fun、a、b这三个函数,也就是三个闭包。

...

形如@63185是对象唯一标识。
context就是执行上下文。
previous表示当前执行上下文的上级执行上下文。
可以看到,a和b这两个函数所在的执行上下文的上级执行上下文与fun所在的执行上下文相同,都是标识为@63187的对象。
三个函数,三个闭包,三个执行上下文。函数内部的变量a和b都位于context中。
下面是代码运行结果截图,在之Snapshot 2后又分别运行了a和b三次,以显示输出的结果。

可以看到,7780、 5523 和 8360这三个变量值出现在了前面的对象截图中,最后一个值是每次调用时实时生成。
下面的代码演示了修改执行上下文中变量的值:
fun = (function () {
var a = (Math.random() * 10000).toFixed();
var a_1 = "data";
return (function () {
var b = (Math.random() * 10000).toFixed();
var obj = {
getB: function () {
return b;
},
setB: function () {
b = (Math.random() * 10000).toFixed();
},
getA: function () {
return a;
},
setA: function () {
a = (Math.random() * 10000).toFixed();
},
show: function () {
var c = (Math.random() * 10000).toFixed();
return a + " - " + b + " - " + c;
}
};
return obj;
})
})();
a = fun();
b = fun();
运行结果如下:

如果你在Profiles中监视新fun函数所在的执行上下文的时候,会发现a_1这个变量没有出现在执行上下文中,应该是a_1没有在内部函数中被使用,chrome将它优化掉了。
3. 结论
闭包是Javascript的一个重要编程模式,它利用了Javascript固有的特性——执行上下文,能够模拟面向对象中的私有变量这种封装方式。
Javascript本质第二篇:执行上下文的更多相关文章
- JavaScript学习系列之执行上下文与变量对象篇
一个热爱技术的菜鸟...用点滴的积累铸就明日的达人 正文 在上一篇文章中讲解了JavaScript内存模型,其中有提到执行上下文与变量对象的概念.对于JavaScript开发者来说,理解执行上下文与变 ...
- Javascript本质第一篇:核心概念
很多人在使用Javascript之前都至少使用过C++.C#或Java,面向对象的编程思想已经根深蒂固,恰好Javascript在语法上借鉴了Java,虽然方便了Javascript的入门,但要深入理 ...
- 数据库程序接口——JDBC——API解读第二篇——执行SQL的核心对象
结构图 核心对象 Statement Statement主要用来执行SQL语句.它执行SQL语句的步骤为: 第一步:创建statement对象. 第二步:配置statement对象,此步骤可以忽略. ...
- [JavaScript深入系列]JavaScript深入之执行上下文栈(转载)
顺序执行? 如果要问到 JavaScript 代码执行顺序的话,想必写过 JavaScript 的开发者都会有个直观的印象,那就是顺序执行,毕竟: var foo = function () { co ...
- JavaScript深入之执行上下文栈
如果要问到 javascript 代码执行顺序的话,想必写过javascript的开发者都会有个直观的印象,那就是顺序执行,例如: var foo = function(){ console.log( ...
- JavaScript执行上下文
变量声明.函数声明为何会提升?js执行时是如何查找变量的?JavaScript中最基本的部分——执行上下文(execution context) 什么是执行上下文? 当JavaScript代码运行,执 ...
- 了解JavaScript的执行上下文
转自http://www.cnblogs.com/yanhaijing/p/3685310.html 什么是执行上下文? 当JavaScript代码运行,执行环境非常重要,有下面几种不同的情况: 全局 ...
- 前端知识体系:JavaScript基础-原型和原型链-理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题
理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题(原文文档) 1.什么是执行上下文: 简而言之,执行上下文就是当前JavaScript代码被解析和执行时所在环境的抽象概念,Java ...
- 通俗易懂的来讲讲js的函数执行上下文
0.开场白 在平时编写JavaScript代码时,我们并不会和执行上下文直接接触,但是想要彻底搞懂JavaScript函数的话,执行上下文是我们绕不过去的一个知识点. 1.执行上下文栈 JavaScr ...
随机推荐
- TotoiseSVN的基本使用方法
TotoiseSVN的基本使用方法 在 项目管理实践教程一.工欲善其事,必先利其器[Basic Tools]中,我已经讲解了怎样安装TortoiseSVN.在上面的讲解中已经讲了怎么使用VisualS ...
- Python3的tkinter写一个简单的小程序
一.这个学期开始学习python,但是看了python2和python3,最后还是选择了python3 本着熟悉python的原因,并且也想做一些小程序来增加自己对python的熟练度.所以写了一个简 ...
- js转换数据库中DateTime字段类型
在程序中,从数据库中读取到的日期时间类型数据一般是这种格式:"/Date(1355109408000+0800)/" 要经过js函数处理变为格式:'2012-12-10 11:05 ...
- 【MongoDB初识】-其他操作
又发现一种查询写法$wheredb.class.find({$}}) 排重db.class.distinct("stuCount") 一.MapReduce(摘录MongoDB实战 ...
- 关于android 加载https网页的问题
我在加载https网页时出现空白, 因此,我就百度一下,可以发现: webView.setWebViewClient(new WebViewClient(){ @Override public voi ...
- Building a RESTful Web Service
Reference: https://spring.io/guides/gs/rest-service/ 参照上述链接进行操作,使用gradle build. 因为total new to this. ...
- BZOJ2498 : Xavier is Learning to Count
考虑容斥,通过$Bell(p)$的时间枚举所有等价情况. 对于一种情况,强制了一个等价类里面的数都要相同,其它的可以相同也可以不同. 这方案数显然可以通过多项式乘法求得,乘上容斥系数$(-1)^{p- ...
- echo.js 延迟加载图片控件
echo.js的github地址:https://github.com/toddmotto/echo echo是一个独立的JavaScript.轻量级的.延迟图片加载插件,echo压缩后体积不到1 ...
- bootstrap之clearfix
bootstrap之clearfix 在bootstrap辅助类中有那么一类,是这么定义的: 利用clearfix样式清除浮动,但是前提条件是在超小型屏幕上能显示才行(因为其是用visible-xs样 ...
- 使用THINKPHP中的控制器和模块查询数据库
1,自定义一个UserController的控制器,导入tp的控制器与模块执行相应的操作. ----var_dump()方法是判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值. ...