参考 高性能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. [c++] Associative Containers

    关联容器 和 顺序容器 的本质差别在于: 关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素. Reference: http://www.cnblogs.c ...

  2. [Node.js] Node.js项目的持续集成

    原文地址:http://www.moye.me/2016/03/03/nodejs_ci_by_jenkins 引子 持续集成 (Continuous Integration,简称CI)是一种软件工程 ...

  3. java并发编程读书笔记(1)-- 对象的共享

    1. 一些原则 RIM(Remote Method Invocation):远程方法调用 Race Condition:竞态条件 Servlet要满足多个线程的调用,必须是线程安全的 远程对象,即通过 ...

  4. 微信开发之.Net

    撸主是一个新手,最近几天在研究微信服务号交互,上网搜了搜C#的代码,再结合自己的习惯,下面把代码解析一下,其中有些代码非本人原创. 首先,你要有个公众服务号,只有服务号才可以自定义菜单,没有条件的可以 ...

  5. 深度学习中的Data Augmentation方法(转)基于keras

    在深度学习中,当数据量不够大时候,常常采用下面4中方法: 1. 人工增加训练集的大小. 通过平移, 翻转, 加噪声等方法从已有数据中创造出一批"新"的数据.也就是Data Augm ...

  6. MySql安装出现问题---无服务,修改密码

           之前在项目中一直使用的是SqlServer数据库,现在学习下MySql,下面是学习MySql的学习笔记. MySql简介       MySql是一种关联数据库管理系统(关系型),将数据 ...

  7. Sql去重语句

    海量数据(百万以上),其中有些全部字段都相同,有些部分字段相同,怎样高效去除重复? 如果要删除手机(mobilePhone),电话(officePhone),邮件(email)同时都相同的数据,以前一 ...

  8. JS表单验证插件(支持Ajax验证)

    自己编写了一个表单验证插件,支持ajax验证,使用起来很简单. 每个需要验证的表单元素下面有一个span标签,这个标签的class有一个valid表示需要验证,如果有nullable则表示可为空:ru ...

  9. C#再识委托

    从C#1到C#3逐步认识委托,由于C#4与C#5对委托改动并不大,故不作说明. 好久没看.NET了,一直在搞HybridAPP,都忘得差不多了,这也是自己从书中摘下笔迹,供日后翻阅. C# 1 1.什 ...

  10. 导出Excel文件(针对Dev)

    文件类: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System. ...