在上一篇文章《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本质第二篇:执行上下文的更多相关文章

  1. JavaScript学习系列之执行上下文与变量对象篇

    一个热爱技术的菜鸟...用点滴的积累铸就明日的达人 正文 在上一篇文章中讲解了JavaScript内存模型,其中有提到执行上下文与变量对象的概念.对于JavaScript开发者来说,理解执行上下文与变 ...

  2. Javascript本质第一篇:核心概念

    很多人在使用Javascript之前都至少使用过C++.C#或Java,面向对象的编程思想已经根深蒂固,恰好Javascript在语法上借鉴了Java,虽然方便了Javascript的入门,但要深入理 ...

  3. 数据库程序接口——JDBC——API解读第二篇——执行SQL的核心对象

    结构图 核心对象 Statement Statement主要用来执行SQL语句.它执行SQL语句的步骤为: 第一步:创建statement对象. 第二步:配置statement对象,此步骤可以忽略. ...

  4. [JavaScript深入系列]JavaScript深入之执行上下文栈(转载)

    顺序执行? 如果要问到 JavaScript 代码执行顺序的话,想必写过 JavaScript 的开发者都会有个直观的印象,那就是顺序执行,毕竟: var foo = function () { co ...

  5. JavaScript深入之执行上下文栈

    如果要问到 javascript 代码执行顺序的话,想必写过javascript的开发者都会有个直观的印象,那就是顺序执行,例如: var foo = function(){ console.log( ...

  6. JavaScript执行上下文

    变量声明.函数声明为何会提升?js执行时是如何查找变量的?JavaScript中最基本的部分——执行上下文(execution context) 什么是执行上下文? 当JavaScript代码运行,执 ...

  7. 了解JavaScript的执行上下文

    转自http://www.cnblogs.com/yanhaijing/p/3685310.html 什么是执行上下文? 当JavaScript代码运行,执行环境非常重要,有下面几种不同的情况: 全局 ...

  8. 前端知识体系:JavaScript基础-原型和原型链-理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题

    理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题(原文文档) 1.什么是执行上下文: 简而言之,执行上下文就是当前JavaScript代码被解析和执行时所在环境的抽象概念,Java ...

  9. 通俗易懂的来讲讲js的函数执行上下文

    0.开场白 在平时编写JavaScript代码时,我们并不会和执行上下文直接接触,但是想要彻底搞懂JavaScript函数的话,执行上下文是我们绕不过去的一个知识点. 1.执行上下文栈 JavaScr ...

随机推荐

  1. java中的小数的取整的几种函数

    Math类中提供了5个与取整相关的函数,如下所示: static double ceil(double a):天花板函数,返回大于等于a的最小整数(但是以浮点数形式存储). static double ...

  2. string,stringbuilder,stringbuffer用法

    总结:1.如果要操作少量的数据用 = String   ==================================>字符串常量2.单线程操作字符串缓冲区 下操作大量数据 = Strin ...

  3. Solr4.10.3安装配置

    系统环境 window版本为:windows 8.1 64位 软件环境 JDK版本:1.7 solr版本:4.10.3 tomcat版本:tomcat 7 安装过程 步骤一:将下载好的solr-4.1 ...

  4. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

    java日期格式大全 format SimpleDateFormat(转) SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH ...

  5. 使用Android Butterknife

    我之前浏览过android butterknife 的使用 在android studio 中,很惊喜,已经成为一个插件来使用 这个android butterknife 最大的用处,就是直接生成la ...

  6. webdav不识别软链接?解决办法?

    webdav不识别软链接?解决办法? 在使用webdav实现公网存储共享的时候,发现webdav并不支持软链接的共享,如下源代码可以100%确定这个问题 /* ### for now, only pr ...

  7. Shell脚本基础

    特别变量: $# 传递到脚本的参数个数$* 以一个单字符串显示所有向脚本传递的参数$$ 脚本运行的当前进程ID号$! 后台运行的最后一个进程的ID号$@ 与$#相同,但是使用时加引号,并在引号中返回每 ...

  8. Object-C与Swift混编

    1.在Object-C项目中调用Swift 1.1.创建一个Object-C project(项目名例如:YYDemo) 如下图 1.2.创建一个Swift Class,如下图 这里会显示是否需要创建 ...

  9. php 搜索(查询)功能

    今天遇到一个问题:在做“搜索”功能时,输入查询条件后查询不了. 我做的是首页显示数据表package中的内容,但是有个条件,显示在首页的内容还必须是 :字段status=0,且printing=0的数 ...

  10. oracle 导出指定的存储过程

    只能导出以下类型: PROCEDURE PACKAGE PACKAGE BODY TYPE BODY FUNCTION TYPE 也就是,表需要单独导出并导入(已经能俭省很多手动操作了). SET e ...