JS运行在程序中提取一个包含代码的字符串,然后动态执行它。有四种标准法可以实现:eval()、Function()构造函数、setTimeout()和setInterval()。其中每个方法都允许传入一个JS代码字符串并执行它。
当在JS代码中执行另一段JS代码时,都会导致双重求值的性能消耗。在实际项目中,避免使用eval()和Function(),而对于setTimeout()和setInterval(),建议传入函数而不是字符串来作为第一个参数。
避免双重求值是实现JS运行期性能最优化的关键所在。
Object/Array直接量JS创建对象和数组的方法中,对象和数组直接量是最快的方式。
//创建一个对象
var obj = {
name: 'Andy',
count: 5,
flag: true,
pointer: null
};
//创建一个数组
var arr = ['Andy', 50, true, null];
最常见的重复工作就是浏览器探测。典型的跨浏览器代码写法:
function addHandler(target, eventType, handler) {
if (target.addEventListener) {
target.addEventListener(eventType, handler, false);
} else {
target.attachEvent("on" + eventType, handler);
}
}
function removeHandler(target, eventType, handler) {
}
第一种消除函数中的重复工作的方法时延迟加载。采用延迟加载的函数版本:
function addHandler(target, eventType, handler) {
if (target.addEventListener) {
addHandler = function (target, eventType, handler) {
target.addEventListener(eventType, handler, false);
}
} else {
addHandler = function (target, eventType, handler) {
target.attachEvent("on" + eventType, handler);
}
}
//调用新函数
addHandler(target, eventType, handler);
}
function removeHandler(target, eventType, handler) {
}
当一个函数在页面中不会立刻调用时,延迟加载是最好的选择。
条件预加载会在脚本加载期间提前检测,而不会等到函数被调用。
var addHandler = document.body.addEventListener ?
function (target, eventType, handler) {
target.addEventListener(eventType, handler, false);
} : function (target, eventType, handler) {
target.attachEvent("on" + eventType, handler);
};
条件预加载适用于一个函数马上就要被用到,并且在整个页面的生命周期中频繁出现的场合。
JS中的数字都以64位格式存储。在位操作中,数字被转换为有符号的32位格式。每次运算符都会直接操作该32位数以得到结果。
AND按位与
两个操作数的对应位都是1时,该位返回1。
OR按位或
两个操作数的对应位只要有一个是1时,该位返回1。
XOR按位异或
两个操作数的对应位只有一个时1时,该位返回1。
NOT按位取反
遇到0则返回1,反之亦然。
采用对2取模运算实现表格行颜色交替。通过让给定数字与数字1进行按位与运算进行判断。
for (var i = o, len = rows.length; i < len; i++) {
if (i & 1) {//对2取模运算 if (i % 2) {}
className = "even";
} else {
className = "odd";
}
//增加class
}
改进后的按位与操作比对2取模操作快了50%
第二种使用位运算的技术称为位掩码。其思路是使用单个数字的每一位来判断是否选项成立,从而有效地把数字转换为布尔值标记组成的数组。掩码中的每个选项的值都等于2的幂。
JS也支持按位左移
<<,按位右移>>和无符号右移等位运算符。
原生的querySelector()和querySelectorAll()方法完成任务平均所需时间是基于JS的CSS查询的10%。
当原生方法可用时,尽量使用它们。特别是数学运算和DOM操作。
为了编写更高效的代码,使用以下编程实践:
eval()和Function()构造器来避免双重求值带来的性能消耗。给setTimeout()和setInterval()传递函数而不是字符串作为参数。