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