参考 高性能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. Android序列化之Serializable和Parcelable

    PS:还有几天就开学了.先来一发. 学习内容: 1.序列化的目的 2.Android中序列化的两种方式 3.Parcelable与Serializable的性能比较 4.Android中如何使用Par ...

  2. git代码回滚:Reset、Checkout、Revert的选择

    代码回滚:Reset.Checkout.Revert的选择 Zhongyi Tong edited this page on Dec 8, 2015 · 5 revisions Pages 19 Ho ...

  3. Theano入门神经网络(四)

    这一部分主要介绍用Theano 实现softmax函数. 在多分类任务中经常用到softmax函数,首先上几个投影片解释一下 假设目标输出是y_hat ,激活函数后的Relu y 一个是1.2 一个是 ...

  4. ElasticSearch 配置详解

    配置文件位于es根目录的config目录下面,有elasticsearch.yml和logging.yml两个配置,主配置文件是elasticsearch.yml,日志配置文件是logging.yml ...

  5. Oracle Flashback和RMAN示例

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5346833.html 环境: Windows 10 专业版 Oracle Database 12c R ...

  6. ASP.NET MVC 四种传值方法

    1.后台传值: public class DataController : Controller { // GET: Data public ActionResult Index() { //1 Vi ...

  7. 利用bootstrap的modal组件自定义alert,confirm和modal对话框

    由于浏览器提供的alert和confirm框体验不好,而且浏览器没有提供一个标准的以对话框的形式显示自定义HTML的弹框函数,所以很多项目都会自定义对话框组件.本篇文章介绍自己在项目中基于bootst ...

  8. 抓取代理IP

    写脚本从指定网站抓取数据的时候,免不了会被网站屏蔽IP.所以呢,就需要有一些IP代理.随便在网上找了一个提供免费IP的网站西刺做IP抓取.本次实践抓取的是其提供的国内匿名代理.可以打开网站查看一下源码 ...

  9. [译]学习IPython进行交互式计算和数据可视化(一)

    --学习IPython进行交互式Python编程.高性能数字计算和数据可视化 作者:Cyrille Rossant 译者:Tacey Wong 注:仅为个人翻译及学习,多有谬处,E文尚可的推荐阅读英文 ...

  10. 数论 - Funny scales(SPOJ - SCALE)

    Funny scales Problem's Link ------------------------------------------------------------------------ ...