js中有四种基本的数据存取位置。分别是:字面量、本地变量、数组元素、对象成员。

字面量:只代表自身,不存储在特定位置。js的字面量有:字符串、数字、布尔值、对象、数组、函数、正则表达式、以及特殊的null和undefined。

本地变量:开发人员使用关键字var定义的数据存储单元。

数组元素:存储在js数组对象内部,以数字作为索引。

对象成员:存储在js对象内部,以字符串作为索引。

总体来说:字面量和本地变量的访问速度快于数组项和对象成员的访问速度。

管理作用域:

  • 作用域链和标示符解析

作用域链:内部属性[[scope]]包含了一个函数被创建的作用域中对象的集合。

函数的作用域链决定了哪些数据能被函数访问。函数作用域中的每个对象被称为一个可变对象,每个可变对象都以“键值对”的形式存在。当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象所填充。

例:function add(num1,num2){

var sum = num1+num2;return sum;

}

当函数add()创建时,它的作用域链中插入了一个对象变量,这个全局对象代表着所有在全局范围内定义的变量。

函数add()的作用域将会在执行时用到。假设执行:var total = add(5,10); 执行此函数时会创建一个称为执行环境的内部对象。一个执行环境定义了一个函数执行时的环境。函数执行时对应的执行函数都是独一无二的,所以多次调用同一个函数就会导致创建多个执行环境。当函数执行完毕后,执行环境就被销毁。

每个执行环境都有自己的作用域链,用于解析标示符。当执行环境被创建时,它的作用域链初始化为当前运行函数的[[scope]]属性的对象。这时会创建一个被称为“活动对象”。活动对象作为函数运行时的变量对象,包含了所有局部变量,命名参数,参数集合以及this。同时被推入作用域链的最前端。执行环境销毁后,活动对象也随之销毁。

在函数执行过程中,每遇到一个变量,都会经历一次标示符解析过程以决定从哪里获取或存储数据。而此搜索过程影响了性能。

标示符解析:

一个标示符所在的位置越深,它的读写速度也就越慢。

经验法则:如果某个跨作用域的值在函数中被引用一次以上,那么就把它存储到局部变量里。访问跨作用域的值,需要遍历作用域链往上找,会导致性能的下降,而通过局部变量存储一个跨作用域的值,使得查找次数减少,性能提升。

作用域链的改变:with语句、try-catch语句中的catch子句将临时改变作用域链,创建一个新的变量对象,并推入作用域链的首位,使得函数的所有局部变量处于第二作用域链的对象,导致访问代价提高。

动态作用域:with、try-catch的catch以及eval()被认为是动态作用域。动态作用域只存在于代码执行过程中,因此无法通过静态分析检测。某些优化的js引擎尝试通过分析代码来确定哪些变量可以在特定时候被访问。这些引擎试图避开传统作用域链的查找,取代以标示符索引的方式进行快速查找。而涉及动态作用域时,这种优化方式失效,脚本引擎切换回较慢的基于哈希表的标示符识别方式。

闭包:由于闭包的特性,将导致存在于闭包的[[scope]]属性中,活动对象无法被销毁,故引起更多的内存开销。因此在使用闭包时最需要关注的性能点:在频繁访问跨作用域的标示符时,每次访问都会带来性能损失。闭包的使用关系到内存和执行速度。

  • 对象成员

js中的对象是基于原型的。原型是其他对象的基础,它定义并实行了一个新创建的对象所必须包含的成员列表。对象有两种成员类型:实例成员和原型成员。实例成员直接存在对象的实例中,原型成员则从对象的原型继承而来。

而在调用原型成员时,搜索过程会深入原型链中直到找到原型成员。而原型成员所在原型链的位置越深,访问所需时间就越多。

嵌套成员:js每次遇到点操作符时,嵌套成员会导致js引擎搜索所有对象成员。例如:location.href比window.location.href读取速度更快。

注:大部分游览器对于点表示法操作和括号表示法操作并没有明显区别,只有Safari中,点符号始终更快。

由于所有类似的性能问题都与对象成员有关,故因尽可能避免使用它们,或者说只在必要时使用对象成员。例如:多次读取同一个对象属性时,最佳做法是将属性值保存到局部变量以此来避免多次查找带来的性能开销。特别是处理嵌套对象成员时。

注:这种优化方式并不推荐用于对象的成员方法,因为许多对象方法使用this来判断执行环境,把一个对象方法保存在局部变量会导致this绑定到window,而this值的改变会使得js引擎无法正确解析它的对象成员,进而报错。

高性能javascript(记录二)的更多相关文章

  1. 高性能JavaScript笔记二(算法和流程控制、快速响应用户界面、Ajax)

    循环 在javaScript中的四种循环中(for.for-in.while.do-while),只有for-in循环比其它几种明显要慢,另外三种速度区别不大 有一点需要注意的是,javascript ...

  2. 《高性能javascript》 领悟随笔之-------DOM编程篇(二)

    <高性能javascript> 领悟随笔之-------DOM编程篇二 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...

  3. JavaScript学习记录二

    title: JavaScript学习记录二 toc: true date: 2018-09-13 10:14:53 --<JavaScript高级程序设计(第2版)>学习笔记 要多查阅M ...

  4. 《高性能Javascript》 Summary(二)

    第四章.算法和流程控制 Algorithms And Flow Control 原因:代码整体结构是执行速度的决定因素之一.代码量少不一定运行速度快,代码量多不一定运行速度慢.性能损失与组织代码和具体 ...

  5. 高性能JavaScript(1)

    ---------------------------------------------------------------------------------------------------- ...

  6. 《高性能javascript》一书要点和延伸(上)

    前些天收到了HTML5中国送来的<高性能javascript>一书,便打算将其做为假期消遣,顺便也写篇文章记录下书中一些要点. 个人觉得本书很值得中低级别的前端朋友阅读,会有很多意想不到的 ...

  7. 高性能JavaScript 重排与重绘

    先回顾下前文高性能JavaScript DOM编程,主要提了两点优化,一是尽量减少DOM的访问,而把运算放在ECMAScript这一端,二是尽量缓存局部变量,比如length等等,最后介绍了两个新的A ...

  8. 【读书笔记】读《高性能JavaScript》

    这本<高性能JavaScript>讲述了有关JavaScript性能优化的方方面面,主要围绕以下几个方面: 1> 加载顺序 2> 数据访问(如怎样的数据类型访问最快,怎样的作用 ...

  9. 《高性能javascript》学习总结

    本文是学习<高性能javascript>(Nichols C. Zakes著)的一些总结,虽然书比较过时,里面的知识点也有很多用不上了,但是毕竟是前人一步步探索过来的,记录着javascr ...

  10. 《高性能JavaScript》--读书笔记

    第一章 加载和运行 延迟脚本 defer 该属性表明脚本在执行期间不会影响到页面的构造,脚本会先下载但被延迟到整个页面都解析完毕后再运行.只适用于外部脚本 <script src="j ...

随机推荐

  1. word域1

    Description: 域是WORD中的一种特殊命令,它由花括号.域名(域代码)及选项开关构成.域代码类似于公式,域选项并关是特殊指令,在域中可触发特定的操作.在用WORD处理文档时若能巧妙应用域, ...

  2. android Fragment 使用

    一 .Fragment的理解 Fragment 与activity 相似,但比activity 多出几个方法 ,Fragment的生命周期小于activity 一个Activity 中可以包含多个Fr ...

  3. EF CodeFirst 关系配置

    自从开始学习asp.net mvc采用code first以来,关系配置就没有搞清楚过!(⊙﹏⊙)b 笔记之前先感谢以下文章和博主,对他们表示崇拜,由浅入深.举例恰当.拨云见日.茅塞顿开,还有什么词, ...

  4. jq

    1: http://jquery.cuishifeng.cn/index.html jquery 学习查询首页<br> 2: http://m.oschina.net/blog/75741 ...

  5. 1010. Radix (25)(未完成)

    Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The an ...

  6. JSON生成c#类代码小工具

    JSON生成c#类代码小工具 为什么写这么个玩意 最近的项目中需要和一个服务端程序通讯,而通讯的协议是基于流行的json,由于是.net,所以很简单的从公司代码库里找到了Newtonsoft.dll( ...

  7. html5画布基础

    canvas 元素用于在网页上绘制图形. 什么是canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canva ...

  8. mysql mybatis-generator plugin 有page实体类的分页

    page实体类 package cn.zsmy.tmp; import java.io.Serializable; /** * 分页对象. * */public final class Page im ...

  9. 创建ajax异步对象方法

    ajax的xmlhttp对象创建: function createXmlHttp(){ var xmlHttp; try{ // Firefox, Opera 8.0+, Safari xmlHttp ...

  10. zabbix3.0.4 部署之九 (zabbix3.0.4 Linux Agent安装)

    1.从官网现在源码镜像   http://nchc.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/3.2.1/zabbix-3. ...