参考 高性能javascript Tom大叔深入理解javascript系列

相关概念

1.执行上下文

  当控制器转到ecmascript可执行代码的时候,就会进入一个执行上下文,执行上下文是以堆栈的方式进行管理的,也就是最底层是全局的上下文,最顶层是当前的执行上下文,每当进入function(包括递归调用)或者eval,都会产生执行上下文压入堆栈,随着函数或者eval的结束,对应的执行上下文被弹出.每当遇到return语句的时候就会推出当前的执行上下文,代码执行完毕后,管理执行上下文的堆栈只会包含全局的上下文

eval('var x = 10');

(function foo() {
eval('var y = 20');
})(); alert(x); //
alert(y); // "y" 提示没有声明

eval在执行的时候会产生调用上下文,而eval的执行会影响到这个调用上下文的状态(数据)

上面的例子中  第一个eval执行的时候会产生调用上下文,它的调用上下文是全局上下文,也就是这个eval操作会对全局上下文产生影响,第二个eval的调用上下文是函数foo的执行上下文,这个eval操作只会影响到foo的指向上下文,当foo函数执行完毕,foo的执行上下文弹出堆栈,所以在全局上下文中y并没有定义

2.变量对象

  变量对象是管理执行上下文相关变量的一种机制,通过变量对象我们能知道如何访问上下文对象中的变量,它是一个与执行上下文相关的特殊对象,它储存着执行上下文中的变量 函数声明 函数形参

在全局的上下文中全局对象自身就是变量对象(理解 因为全局上下文中的变量对象就是全局对象,声明在全局的变量相当于向全局上下文的变量对象中添加属性,也就是向全局对象中添加属性 )

在函数上下文中,变量对象这个概念被活动对象所替换,在进入函数上下文的时刻活动对象通过arguments属性初始化

  function test(x) {
console.log(x);
console.log(arguments[0]);
arguments[0] = 100;
console.log(x);
}
test(1);//形参 和 arguments 之间的数据共享

处理上下文代码分为两个阶段,进入执行上下文  执行代码

进入执行上下文阶段  变量对象包含下列的值  函数所有的形式参数(键值对)  所有函数声明  所有的变量声明(不会干扰在变量对象中存在的同名字的形式参数和函数声明)

代码执行阶段  其实就是对进入执行上下文阶段初始化值的赋值过程

理解函数声明的提升  

alert(x); // function
var x = 10;
alert(x); // 10
x = 20;
function x() {
console.log(1);
};

在进入执行上下文的阶段,变量的声明是在函数的形式参数声明和函数声明之后的,并且变量的声明不会影响函数的声明,所以在进入执行上下文阶段的变量对象中x的值是指向声明的函数 在执行阶段在对变量的值进行修改

3.变量

  变量只能通过var关键字进行声明

a = 10;
var b = 10;

在上面的代码中进入执行上下文阶段 变量对象中只包含b undefined  不存在a 之所以存在一种观点任何不通过var声明的变量都会转变成全局变量 是因为在代码执行阶段 比如执行到 a = 10的时候,由于此时的变量对象就是全局对象,并且我们访问全局对象的属性的时候是可以省略全局对象的前缀的(也就是this或者window),所以这句话相当于在全局对象中添加属性,并没有声明一个变量  属性是可以删除的 但是变量是不可以删除的 特例

eval("var a = 10;");
console.log(delete a);//true
var b = 10;
console.log(delete b);//false

3 作用链域

在每个执行上下文中都有一个变量对象(函数执行上下文活动对象),作用链域正是存储这些变量对象(包括父级的变量对象的列表),通过作用链域进行标示符的解析,函数的作用链域在函数调用时进行创建

如何进行标示符解析

var x = 10;
function test() {
var y = 20;
console.log(x+y);
} test();

上面的例子中在全局上下文中的变量对象中是存在变量X 函数test  在函数test的活动对象中存在着变量y 但是函数执行的过程中能到查找到x,也就是在test的执行上下文中能够查找到x 这个机制是什么呢? 就是通过[[scope]]属性,这个属性在函数创建的时候被创建,包含父级上下文的所有变量对象加上自身的变量对象(活动对象)构成作用链域(也就是存在当前的变量对象的变量或者函数声明屏蔽父级变量对象的变量或者函数声明),[[scope]]在函数创建创建的时候被存储,它是静态的属性

var x = 10;
function test(){
var x = 10;
console.log(x);
}
test();

上面的例子中在test的作用链域中是有test的活动对象 + [[scope]]组成,当前test的上下文中[[scope]]属性值只包含全局上下文的变量对象也就是全局对象,在标示符解析的过程中优先从作用链域的顶端test的活动对象中查找,在通过[[scope]]属相沿着父级的变量对象一级一级进行查找,知道找到相应的变量或者函数声明,未找到返回undefined

例外 通过Function创建的函数的[[scope]]中只包含全局对象

正文 

  在执行链域中处于深层的标示符解析的时候,因为要通过作用链域进行查找,位置越深的读取速度也就越慢,以下是提供标示符解析性能的一些方法

(1)缓存跨作用域的值

function test() {
var doc = document;
var getId = doc.getElementById("aa");
}

在函数中缓存全局变量的document属性,在函数test中进行多次使用的时候,就能减少变量查找的过程

(2)在通过原型链进行查找的过程中,对象成员的层次越深,查找的性能越慢,多次进行读写的话也就更加降低性能,所以涉及到对对象成员的查找的时候也进行一定的缓存

(3)避免使用with语句 with会在作用链域的开头加入新的对象对象从而导致原来的变量对象处于作用链域的第二位置,降低了访问的性能

高性能javascript学习笔记系列(2)-数据存取的更多相关文章

  1. 高性能javascript学习笔记系列(6) -ajax

    参考 高性能javascript javascript高级程序设计 ajax基础  ajax技术的核心是XMLHttpRequest对象(XHR),通过XHR我们就可以实现无需刷新页面就能从服务器端读 ...

  2. 高性能javascript学习笔记系列(5) -快速响应的用户界面和编程实践

    参考高性能javascript 理解浏览器UI线程  用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程  UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 ...

  3. 高性能javascript学习笔记系列(1) -js的加载和执行

    这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令 ...

  4. 高性能javascript学习笔记系列(4) -算法和流程控制

    参考高性能javascript for in 循环  使用它可以遍历对象的属性名,但是每次的操作都会搜索实例或者原型的属性 导致使用for in 进行遍历会产生更多的开销 书中提到不要使用for in ...

  5. 高性能javascript学习笔记系列(3) -DOM编程

    参考 高性能javascript 文档对象模型(DOM)是独立于语言的,用于操作XML和HTML文档的程序接口API,在浏览器中主要通过DOM提供的API与HTML进行交互,浏览器通常会把DOM和ja ...

  6. 高性能javascript 学习笔记(1)

    加载和运行 管理浏览器中的javascript代码是个棘手的问题,因为代码运行阻塞了其他浏览器处理过程,诸如用户绘制,每次遇到<script>标签,页面必须停下来等待代码下载(如果是外部的 ...

  7. JavaScript学习笔记系列2:Dom操作(一)

    一.什么是Dom? DOM------>Document Object Model 直接翻译就是文档对象模型. DOM------>定义了表示和修改文档所需的对象.这些对象的行为和属性以及 ...

  8. JavaScript学习笔记系列1:JavaScript的是什么?

    一.JS是什么? JavaScript作为Netscape Navigator浏览器的一部分首次出现在1996年.它最初的设计目标是改善网页的用户体验. 作者:Brendan Eich 期初JavaS ...

  9. Dynamic CRM 2013学习笔记 系列汇总

    这里列出所有 Dynamic CRM 2013学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址: Dynamic CRM 2013学习笔记 系列汇总 ...

随机推荐

  1. 构建自己的PHP框架--抽象Controller的基类

    上一篇博客中,我们将简单的路由解析和执行,从入口文件public/index.php中移入到框架中.入口文件顿时变得清爽无比-- 但是,去我们的controller里看一下,会看到如下的code: p ...

  2. 微信内置浏览器WebApp开发,踩坑 · Issue #31 · maxzhang/maxzhang.github.com · GitHub

    最近花6天时间完成了一个七夕的小活动,是一个简单的WebApp.由于我前期对面向微信的Web开发评估不足,导致开发过程十分艰难.写这篇文章总结下,惊醒自己未来不要再犯这样的错误. 问题: 1. 有些比 ...

  3. PHP面试出场率较高的题目<转载>

    --------------------PHP部分--------------------- PHP中几个输出函数echo,print(),print_r(),sprintf(),var_dump() ...

  4. nginx反向代理docker registry报”blob upload unknown"解决办法

    问题症状:keepalived+nginx反向代理后端docker registry群集时,使用docker客户机向registry push镜像时出现 "blob upload unkno ...

  5. Deep learning:四十四(Pylearn2中的Quick-start例子)

    前言: 听说Pylearn2是个蛮适合搞深度学习的库,它建立在Theano之上,支持GPU(估计得以后工作才玩这个,现在木有这个硬件条件)运算,由DL大牛Bengio小组弄出来的,再加上Pylearn ...

  6. 帮助你实现漂亮界面的14套免费的 HTML/CSS 源码

    在网络上能找很多免费的 PSD 格式素材,但是很少有 HTML/CSS 界面组件下载.在这篇文章中,收集了14套免费的 HTML/CSS 界面源码分享给前端设计师和开发者们.这些组件包括按钮.滑块.表 ...

  7. java类加载器-Tomcat类加载器

    在上文中,已经介绍了系统类加载器以及类加载器的相关机制,还自定制类加载器的方式.接下来就以tomcat6为例看看tomat是如何使用自定制类加载器的.(本介绍是基于tomcat6.0.41,不同版本可 ...

  8. linux service命令解析

      我们平时都会用service xxx start来启动某个进程,那么它背后究竟执行了什么? 其实service的绝对路径为/sbin/service ,打开这个文件cat /sbin/servic ...

  9. 【转】ASP.NET"正在中止线程"错误原因

    最近做的系统中老出现的一些问题不太明白,在使用 Response.End.Response.Redirect 或 Server.Transfer 时出现 ThreadAbortException , ...

  10. C语言学习013:通过make编译C源代码

    编译多个C源代码文件 当程序文件越来越多,修改了其中的一部分代码文件,我们并不需要全部重新编译,只需要编译其中一部分就可以,下面我们创建了一个launch程序,除了主程序,我们创建了3个功能代码文件r ...