V8引擎常见去优化原因
arguments相关
在非严格模式下,对一个已经被定义,同�时在函数体中被arguments引用的参数重新赋值
// 常见错误
// 只会在函数中重新赋值参数发生。
function demo(b) {
if (arguments.length < 1) b = 5;
}
// �优化方式1
function demo(b_) {
var b = b_;
if (arguments.length < 1) b = 5;
}
// 优化方式2
开启严格模式 ('use strict')
// 优化方式3
V8 最新的 TurboFan 会有优化
对arguments进行错误的处理
// 直接赋值
function test1() {
arguments[0] = 0;
}
function test2() {
arguments.length = 0;
}
// 对外暴露arguments
function test3() {
return arguments;
}
function test5() {
var a = arguments;
return function() {
return a;
};
}
// 优化方案
// 避免以上操作
// 如果必须要暴露,可以通过创建一个数组来代理 arguments 对象
function doesntLeakArguments() {
//.length 仅仅是一个整数,不存在泄露
//arguments 对象本身的问题
var args = new Array(arguments.length);
for(var i = 0; i < args.length; ++i) {
//i 是 arguments 对象的合法索引值
args[i] = arguments[i];
}
return args;
}
for in相关
key不是局部变量
// 常见错误
var key;
function demo() {
var obj = {}
for(key in obj);
}
function demo() {
var obj = {}
for(var key in obj) {
return function() {
return key;
};
}
}
// 优化方式
键不能在上级作用域定义,也不能在下级作用域被引用
forin中包含太多代码
// 常见错误
for (var prop in obj) {
/* lots of code */
}
// 优化方式
for 循环中的提取代码提取为函数。
for-in 遍历一个非简单可枚举对象
- 处于”哈希表模式“
- 如果你给一个对象动态增加了很多的属性(在构造函数外)、delete 属性或者使用不合法的标识符作为属性,这个对象将会变成哈希表模式。
- 对象的原型链中存在可枚举属性
Object.prototype.fn = function() {};
- 上面这么做会给所有对象(除了用 Object.create(null) 创建的对象)的原型链中添加一个可枚举属性。此时任何包含了 for-in 语法的函数都不会被优化(除非仅遍历Object.create(null) 创建的对象)。
- 你可以使用 Object.defineProperty 创建不可枚举属性
- 对象中包含可枚举数组索引,或遍历数组
// 如果你试图使用 for-in 遍历一个非简单可枚举对象,它会导致包含它的整个函数不能被优化。
// 优化方式
// 只对 Object.keys 使用 for-in,如果要遍历数组需使用 for 循环
// 如果非要遍历整个原型链上的属性,需要将 for-in 隔离在一个辅助函数中以降低影响
try catch相关
try catch中存在太多代码
// 常见错误
// try/catch 使得控制流不稳定,很难在运行时优化.
function demo() {
try {
/* lots of code */
} catch(e) {
/* ... */
}
}
// 优化方案
// 不要讲它放在计算密集型函数中
// try中内容单独提出函数,try { test() } catch
存在太多参数
function test(p1, p2, p3, ..., p512) {
}
使用Rest parameters
// 常见错误
function test(...rest) {
return rest[0];
}
// 优化方案
// 避免使用reset,或者使用babel编译
参考