javascript的数据访问

 在javascript中有四种基本的数据访问位置:

1.直接量:

直接量仅仅代表自己,而不存储于特定位置。 JavaScript 的直接量包括:字符串,数字,布尔值,对象,

数组,函数,正则表达式,具有特殊意义的空值,以及未定义。

2.变量:

开发人员使用var 关键字创建用于存储数据值。

3.数组项

具有数字索引,存储一个JavaScript 数组对象。

4.对象成员

具有字符串索引,存储一个JavaScript 对象。

在大多情况下,对一个直接量和一个局部变量数据访问的性能差异是微不足道的。访问数组项和对象成员的代价要高一点,具体高多少,很大程序上依赖于浏览器。

几个重要概念:作用域链,标识符(此处不作详解,具体翻阅相关书籍)

标识符识别性能:

标识符识别不是免费的,事实上没有哪种电脑操作可以不产生性能开销。在运行期上下文的作用域链中,一个标识符所处的位置越深,它的读写速度就越慢。所以,函数中局部变量的访问速度总是最快的,而全局变量通常是最慢的(优化的JavaScript 引擎在某些情况下可以改变这种状况)。请记住,全局变量总是处于运行期上下文作用域链的最后一个位置,所以总是最远才能触及的。对所有浏览器来说,一个标识符所处的位置越深,读写它的速度就越慢

例子:

function initUI(){
var bd = document.body,
links = document.getElementsByTagName_r("a"),
i = 0,
len = links.length;
while(i < len){
update(links[i++]);
}
document.getElementById("go-btn").onclick = function(){
start();
};
bd.className = "active";
}

 此函数包含三个对document的引用,document是一个全局对象,搜索此变量,必须要遍历整个作用域链,直到最后在全局变量对象中找到它。你可以通过将全局变量的引用存储在一个局部变量中,然后局部变量

代替全局变量。

function initUI(){
var doc = document,
bd = doc.body,
links = doc.getElementsByTagName_r("a"),
i = 0,
len = links.length;
while(i < len){
update(links[i++]);
}
doc.getElementById("go-btn").onclick = function(){
start();
};
bd.className = "active";
}

改变作用域链:

1.使用with表达式(不建议使用)

function initUI(){
with (document){ //avoid!
var bd = body,
links = getElementsByTagName_r("a"),
i = 0,
len = links.length;
while(i < len){
update(links[i++]);
}
getElementById("go-btn").onclick = function(){
start();
};
bd.className = "active";
}
}

 
javascript的数据访问
 通过将document 对象传递给with 表达式,一个新的可变对象容纳了document 对象的所有属性,被插入

到作用域链的前端。这使得访问document 的属性非常快,但是访问局部变量的速度却变慢了,例如bd 变

量。正因为这个原因,最好不要使用with 表达式。正如前面提到的,只要简单地将document 存储在一个

局部变量中,就可以获得性能上的提升。

2.try-catch表达式的catch子句:

当try 块发生错误时,程序流程自动转入catch 块,并将异常对象推入作用域链前端的一个

可变对象中。在catch 块中,函数的所有局部变量现在被放在第二个作用域链对象中。

try {
methodThatMightCauseAnError();
} catch (ex){
handleError(ex); //delegate to handler method
}

 请注意,只要catch 子句执行完毕,作用域链就会返回到原来的状态。

handleError()函数是catch 子句中运行的唯一代码。此函数以适当方法自由地处理错误,并接收由错误产

生的异常对象。由于只有一条语句,没有局部变量访问,作用域链临时改变就不会影响代码的性能。

动态作用域:(不建议使用)

无论是with 表达式还是try-catch 表达式的catch 子句,以及包含()的函数,都被认为是动态作用域。一

个动态作用域只因代码运行而存在,因此无法通过静态分析(察看代码结构)来确定(是否存在动态作用

域)

嵌套对象成员会造成重大性能影响,尽量少用。

一个属性或方法在原形链中的位置越深,访问它的速度就越慢。

一般来说,你可以通过这种方法提高JavaScript 代码的性能:将经常使用的对象成员,数组项,和域外变量存入局部变量中。然后,访问局部变量的速度会快于那些原始变量。

相关推荐