Recently we’ve been using JS quite extensively.
Here’s a few things in JS that should be watched for (as they’re not obvious and not well known):
Numbers are doubles. This means they’re approximations, so don’t expect an exact result:
var d = 0.1 + 0.2; // result is 0.30000000000000004
Loops can have labels, which can be used to break out from those loops:
loopOne: for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (j == 3) break loopOne; console.log(i + " " + j); } }
This will stop after printing “0 2”
The ‘for..in’ loop will list properties of a prototype object as well (not unexpected), if you want to test if the property was defined on this specific object – double check with hasOwnProperty() method:
var parent = { name:"Bob", gender:"male" }; var child = function () { this.age = 20; }; child.prototype = parent; var ch = new child(); for (p in ch) { console.log(p + ", is own property: " + ch.hasOwnProperty(p)); }
will print
age, is own property: true name, is own property: false gender, is own property: false
Setting a parent to null or undefined will have no effect on child, but changing its properties value will:
parent.name = "Bill"; delete parent.gender; for (p in ch) { console.log(p + ", is own property: " + ch.hasOwnProperty(p) + ", value: " + ch[p]); }
will print
age, is own property: true, value: 20 name, is own property: false, value: Bill
Blocks don’t have their own scope. Variables defined in blocks will be accessible outside:
for (var i = 0; i < 2; i++) { var boo = 33; } console.log(boo);
will print 33
JS has constructor for its types, which generally should be avoided:
var ba = new Boolean(false); var bb = false, bc = false; console.log(bb === bc); // true console.log(ba == bb); // true console.log(ba === bb); // FALSE!
Be careful when using typeof operator:
console.log(typeof {}); // object console.log(typeof 2); // number console.log(typeof "abc"); // string console.log(typeof null); // OBJECT - this is wrong! console.log(typeof []); // object - not helpful