# 【DailyENJS第12期】V8引擎和JavaScript优化技巧

DailyENJS 致力于翻译优秀的前端英文技术文章，为技术同学带来更好的技术视野。

• 用C ++编写，并在Chrome和Node.js（以及Microsoft Edge的最新版本）中使用
• 实现 ECMA-262 标准

### 解析JavaScript

• 非惰性（完全解析）-这会立即解析每行
• 懒惰（预先解析）-进行最少的工作，解析我们需要的内容，其余部分留到以后

``````// 立即解析
const a = 1;
const b = 2;

// 惰性解析，因为暂时用不到
function add(a, b) {
return a + b;
}

// 因为使用到了，所以返回去 解析

``````// 立即解析
const a = 1;
const b = 2;

// 立即解析
var add = (function(a, b) {
return a + b;
})();

// 当我们使用到这个函数的时候已经被解析了

• Without optimize-js: 11.86ms
• With optimize-js: 11.24ms

``````// bad way
function sumOfSquares(a, b) {
// this is lazily parsed over and over
function square(num) {
return num * num;
}

return square(a) + square(b);
}``````

``````function square(num) {
return num * num;
}

// good way
function sumOfSquares(a, b) {
return square(a) + square(b);
}

sumOfSquares(a, b);``````

### 函数内联

Chrome有时实际上会重写您的JavaScript，其中一个示例是内联正在使用的函数。

``````const square = (x) => { return x * x }

const callFunction100Times = (func) => {
for(let i = 100; i < 100; i++) {
// the func param will be called 100 times
func(2)
}
}

callFunction100Times(square)``````

``````const square = (x) => { return x * x }

const callFunction100Times = (func) => {
for(let i = 100; i < 100; i++) {
// the function is inlined so we don't have
// to keep calling func
return x * x
}
}

callFunction100Times(square)``````

### 函数内联陷阱

``````const square = (x) => { return x * x }
const cube = (x) => { return x * x * x }

const callFunction100Times = (func) => {
for(let i = 100; i < 100; i++) {
// the function is inlined so we don't have
// to keep calling func
func(2)
}
}

callFunction100Times(square)
callFunction100Times(cube)
``````

### Objects

#### Monomorphism

``````// mono example
const person = { name: 'John' }
const person2 = { name: 'Paul' }``````

#### Polymorphism

``````// poly example
const person = { name: 'John' }
const person2 = { name: 'Paul', age: 27 }``````

#### Megamorphism

``````// mega example
const person = { name: 'John' }
const building = { rooms: ['cafe', 'meeting room A', 'meeting room B'], doors: 27 }``````

### 隐藏类（Hidden classes）

``const obj = { name: 'John'}``

``const objClassId = ['name', 1]``

``const obj = {...objClassId, 'John'}``

``obj.name``

V8执行以下查询：

``obj[getProp(obj[0], name)]``

V8是创建对象时经历的过程，现在让我们看看如何优化对象并重用classId。

### 创建对象的技巧

``````class Point {
constructor(x,y) {
this.x = x
this.y = y
}
}

const p1 = new Point(11, 22) // hidden classId created
const p2 = new Point(33, 44)``````

``````const obj = { a: 1 } // hidden class created
obj.b = 3

const obj2 = { b: 3 } // another hidden class created
obj2.a = 1

// this would be better
const obj = { a: 1 } // hidden class created
obj.b = 3

const obj2 = { a: 1 } // hidden class is reused
obj2.b = 3``````

### 修复函数参数类型

``````function add(x,y) {
return x + y
}

add('a', 'b') // polymorphic
add([],[]) // megamorphic - at this stage, 4+ tries, no optimization will happen``````

``````// don't do this
function createPoint(x, y) {
class Point {
constructor(x,y) {
this.x = x
this.y = y
}
}

// new point object created every time
return new Point(x,y)
}

function length(point) {
//...
}``````

3 人关注
13 篇文章