Its dynamic behavior may introduce you to many head-scratching bugs. In this post, I going to cover some pitfalls I have encountered.
1. Function is hoisted, function expression is not
When executing Line(14), browser will throw a error, fn has yet to define by the time fn called.
In contrary, in line(15), function fn2 hoisted to top of block, it will look like below. fn2 has been defined before it is called. Hence, fn2 works as expected.
2. Prototypal inheritance preserve memory, all instance share one copy prototype object
In above snippet, Object.create create a new rabbit object with prototype is animal object. The things is when I change animal.eats = false then the rabbit prototype also change automatically (console.log(rabbit.eats) will print out false).=> Instead of copying, prototypal inheritance only keep a reference to prototype object.
3. Primitive types vs reference types
Line(4) will print out 2 although c has been change. This is happen because when assigning a variable to a variable contain primitive type value (number, string, null, undefined, boolean), it will COPY value. In our sample: line(2) b will copy value on variable c (then b and c have different memory zone)
On the contrary, when assigning a variable to a variable contain reference types (object, array), it only keeps a reference to that variable. In our snippet, line (9) , f keeps a reference to d (this mean f and d have the same memory zone). So when I change d on line (10), f also changes accordingly, automatically.
4. Trick of assignment operator
Surprisingly, line(4) print out value 5, you are swindled. Line(2) can be verbally describe like this “assign number 5 for global variable b and then assign for local variable a”, var keyword only take effect on variable a.