第二章 数据访问
读书笔记:
JavaScript 中有四种基本数据访问位置:
直接量:直接量仅仅代表自己,而不存储特定位置。字符串,数字,布尔,对象,数组,函数,正则表达式,具有特殊意义的空值,以及未定义。
变量:var关键字创建用于存储数据值。
数组项:具有数字索引,存储一个javascript数组对象。
对象成员: 具有字符串索引,存储一个javascript对象。
总的来说, 直接量和局部变量的访问速度要快于数组项和对象成员的访问速度。
管理作用域
每个javascript函数都被表示为对象,进一步说,是一个函数实例。
函数对象正如其他对象一样,拥有你可以编程访问的属性,和一系列不能被程序访问,仅供javascript引擎使用的内部属性。其中一个属性是[scope]作用域。
内部[scope]属性包含一个函数被创建的作用域中的对象的集合。此集合被称为函数的作用域链。它决定哪些数据可由函数访问,此函数作用域链中的每个对象称为一个可变对象,每个可变对象都以“键值”的形式存在。当一个函数创建后,他的作用域链被填充以对象,这些对象代表创建此函数的数据。
在函数运行过程中,每遇到一个变量,标识符识别过程要决定从哪里获得或者存储数据。
此过程搜索运行期上下文的作用域链,查找同名的标识符。从运行函数的激活目标之作用域的前端开始,如果找到了,就使用这个具有指定标识符的变量。 如果没找到,继续搜索,知道标识符被找到。 函数运行时每个标识符都会经过这样的过程,这种搜索过程会影响性能。
在运行期的上下文的作用域链中,一个标识符所处的位置越深,读写速度越慢,所以,局部变量的读写速度是最快的,全局变量通常是最慢的。
在没有优化Javascript引擎的浏览器中,尽可能使用局部变量。
用局部变量存储本地范围之外的变量值,如果它在函数中的使用多于一次。
改变作用域链
一般来说, 一个运行期上下文的作用域链不会改变。但是,有两种表达式可以改变上下文作用域链。
1.With
With(document)创建一个默认操作变量
通过将document对象传递给with表达式,一个新的可变对象容纳了document对象的所有属性。被插入到了作用域的前端。访问document属性非常快,但访问局部变量的速度变慢了,最好不要使用with。正如前面提到的,只要简单的将document存储到局部变量中,就可以获得性能上的提升。
总结:
在javascript中, 数据存储位置可以对代码整体性能产生重要影响。有四种数据访问类型,直接量,数组项,对象成员, 他们有着不同的性能考虑。
直接量和局部变量访问速度非常快, 数组项和对象成员需要更长时间。
局部变量比域外变量快,因为它位于作用域链的第一个对象中。变量在作用域中的位置越深,访问所需的时间就越长,全部变量总是最慢的,因为他们总是位于作用域链的最后一环。
避免使用with表达式,因为它改变了运行期上下文的作用域链,而且应当小心对待try-catch表达式的catch子句,因为它具有同样效果。
嵌套对象会造成重大性能影响,尽量少用。
一个属性或方法在原型链中的位置越深,访问它的速度就越慢。
提高javascript的性能,将经常使用的对象成员,数组项,和域外变量存入局部变量中,然后,访问局部变量的速度就快于那些原始变量。