Vous êtes sur la page 1sur 21

Understanding Javascript

Engine to Code better


Ihsan Fauzi rahman
What is Javascript
Engine ?
SpiderMonkey Chakra

JavaScriptCore Rhino Carakan


Ignition & Turbofan

Ignition Optimized
Code

Optimize
Bytecode Turbofan

Interpreted Optimized
How to Make use of
that ?
Hidden Class
function Point(x, y) {
this.x = x;
A Point Initial Hidden
this.y = y;
Object Class H0
}
var p1 = new Point(1, 2);

A Point Initial Hidden


var p2 = new Point(1, “2”);
Object Class H1

var p3 = new Point(1, 2); A Point Initial Hidden


p3.z = 3; Object Class H3
Inline Cache
Monomorphic

Offset 0: x Offset 0: x
Offset 1: y Offset 1: y

Polymorphic

Offset 0: x
Offset 1: y
Offset 2: z
Optimization Killer
Unsupported Syntax

Workaround
function containsObjectLiteralWithProto() { var errorObject = {value: null};
return {__proto__: 3}; function tryCatch(fn, ctx, args) {
} try {
return fn.apply(ctx, args);
}
catch(e) {
function containsObjectLiteralWithGetter() {
errorObject.value = e;
return {
return errorObject;
get prop() {
}
return 3;
}
}
};
var result = tryCatch(mightThrow, void 0, [1,2,3]);
}
//Unambiguously tells whether the call threw
if(result === errorObject) {
var error = errorObject.value;
function containsObjectLiteralWithSetter() { }
return { else {
set prop(val) { //result is the returned value
this.val = val; }
}
};
}
Unmanaged Arguments

Workaround
function reAssignParam(a, b_) {
function defaultArgsReassign(a, b) { var b = b_;
if (arguments.length < 2) b = 5; //unlike b_, b can safely be reassigned
} if (arguments.length < 2) b = 5;
}
Unmanaged Arguments

Workaround
function doesntLeakArguments() {
function leaksArguments1() { //.length is just an integer, this doesn't leak
return arguments; //the arguments object itself
} var args = new Array(arguments.length);
for(var i = 0; i < args.length; ++i) {
function leaksArguments2() { //i is always valid index in the arguments object
var args = [].slice.call(arguments); args[i] = arguments[i];
} }
return args;
function leaksArguments3() { }
var a = arguments;
return function() { function anotherNotLeakingExample() {
return a; var i = arguments.length;
}; var args = [];
} while (i--) args[i] = arguments[i];
return args
}
Unmanaged Arguments

function assignToArguments() {
arguments = 3;
return arguments; There’s no workaround, just remove this.
}
Switch-Case

function over128Cases(c) {
switch(c) {
case 1: break;
case 2: break;
case 3: break;
... Use if else or Array of Function
case 128: break;
case 129: break;
}
}
For-In

The key is not a local variable

function nonLocalKey1() {
var obj = {}
for(var key in obj);
return function() {
return key;
};
}
Always use local variable

var key;
function nonLocalKey2() {
var obj = {}
for(key in obj);
}
For-In

The object being iterated is not a


“simple enumerable"

function hashTableIteration() {
var hashTable = {"-": 3};
for(var key in hashTable); Use simple enumerable object
}
For-In

The object has enumerable properties


in its prototype chain

Object.prototype.fn = function() {}; Except Object.create(null)


For-In

Always use Object.keys and


iterate over array using for loop
function iteratesOverArray() {
var arr = [1, 2, 3];
for (var index in arr) {
function inheritedKeys(obj) {
var ret = [];
}
for(var key in obj) {
}
ret.push(key);
}
return ret;
}
let

Workaround
let a = 0;
let a = 0, b = 3; let b = 3;

let a = 0; let a = 0;
a += 5; a = a + 5;
For-In

Infinite loops with deep logic exit conditions


or unclear exit conditions

while (true) { for (;;) {


Thank You

Vous aimerez peut-être aussi