javaScript pitfalls

  • Not using “var” :

if you don’t use the var keyword when creating a variable, the JavaScript engine will create a global variable by default.

(function () {
  tax = 0.05;
}());

var totalPrice = 100 + (100 * tax); // 105
The variable tax is available outside the function because it’s not declared with the var keyword. Watch out for this.

The following code ensures each variable is functionally (locally) scoped, even though only the first variable is preceded by the var keyword:

// shorthand #1
function test() {
    var local1 = null,
        local2 = null;
}
test();

// shorthand #2
function test2() {
    var local1, local2;  // these are of type 'undefined' but they have functional scope!
}
test2();

Multiple variable declaration equivalence gives different scope to each variable
Trying to be fancy and declare multiple variables to be the same value, I mistakenly created a global.

function test() {
    var local = global = null;
}
test();

This sets both variables to “null” using the shortest code possible, but unfortunately only the variable “local” is preceded by the var keyword, so only that variable will be in its proper functional scope. Variable “global”, on the other hand, is… well… global.

  • No “block” scope :

Javascript only has two types of scoping – global and functional. There is no block scope.

In java :

 public static void print(){
 for(int i=0;i<10;i++){
 }
 System.out.println(i);
 }

This will result in error “i cannot be resolved to a variable”.

But in javaScript :

 var myFun = function(){
 for(var i=0;i<10;i++) {
 }
 alert(i);
 }

myFun();

  • javaScript “identity (===)” vs “equality (==)” :

JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=. The good ones work the way you would expect. If the two operands are of the same type and have the same value, then === produces true and !== produces false. The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. the rules by which they do that are complicated and unmemorable. These are some of the interesting cases:

” == ‘0’ // false
0 == ” // true
0 == ‘0’ // true

false == ‘false’ // false
false == ‘0’ // true

false == undefined // false
false == null // false
null == undefined // true

‘ \t\r\n ‘ == 0 // true

The lack of transitivity is alarming. My advice is to never use the evil twins. Instead, always use === and !==. All of the comparisons just shown produce false with the === operator.

  • Trailing comma in object definition literal :

Don’t accidentally leave a trailing comma in an object definition literal or IE will fail and you won’t notice until much later because you never use IE for development and by then it could suck figuring out what happened.

var foo = {
bar: "bar",
baz: "baz",
};
  • Not using “;” because it’s “optional” :

JavaScript automatically inserts semicolons whilst interpreting your code, so if you put the value of the return statement below the line, it won’t be returned:

Your Code:

return
5;

JavaScript Interpretation:

return;
5;

Thus, nothing is returned, because of JavaScript’s auto semicolon insertion.

  • Using “for in” loop variant for iterating over Arrays :

Inherited properties are also enumerated.

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
  alert(array[i]);
}

The above code will alert, “a”, “b”, “c” and “foo!”.

  • Using “new Array()” :

because the constructer is ambiguous :

new Array(4);

creates an empty array of length 4. But

new Array('4');

creates an array containing the value ‘4’.

  • Variable Hoisting :

JavaScript essentially moves any variable declarations into the top of the current function.

var i = 5
function testvar () {
     alert(i);
     var i=3;
}
testvar();

the alert window will contain undefined. because internally, it’s been changed into this:

var i = 5
function testvar () {
     var i;
     alert(i);
     i=3;
}
testvar();
  • “this” in Nested function :
function Menu(elem) {

  function privateMethod() {
                alert(this); // window, not menu!
  }
                Menu.prototype.toString = function dogToString() {
                return "Menu";
                }
  // ... call private method
  privateMethod()
}

“this” always refers to the inner function. if you have nested functions, you have to create another variable and point that to this.

function Menu(elem) {
var that = this;
function privateMethod() {
                alert(that); // window, not menu!
}
                Menu.prototype.toString = function dogToString() {
                return "Menu";
                }
  // ... call private method
  privateMethod()
}

new Menu(document.createElement('div'))
  • closure inside loops :

closure of the generated functions contain pointers to variables, not a snapshot of the values at the point of definition.

var funcs = [];
for (var i = 0; i < 3; i++) {          // let's create 3 functions
    funcs[i] = function() {            // and store them in funcs
        alert("My value: " + i); // each should log its value.
    };
}
for (var j = 0; j < 3; j++) {
    funcs[j]();                        // and now let's run each one to see
}

we can artificially introduce scopes by creating new functions and immediately invoking them:

var funcs = [];

for (var i = 0; i < 3; i++) {
    funcs[i] = (function(index) {
        return function() {
            alert("My value: " + index);
        }
    })(i);
}
for (var j = 0; j < 3; j++) {
    funcs[j]();
}
  • array.sort() on an array consisting of numbers :
var myarray=[7, 40, 300]
myarray.sort() //Array now becomes [300,40,7]

Although 7 is numerically smaller than 40 or 300, lexicographically, it is larger, so 7 appears at the very right of the sorted array. Remember, by default array.sort()sorts its elements in lexicographical order.

  • Type Detection

Since JavaScript is a loosely-typed language, it is sometimes necessary to examine a value to determine its type. (This is sometimes necessary in strongly typed languages as well.) JavaScript provides a typeof operator to facilitate this, but typeof has problems.


Object 'object'
Array 'object'
Function 'function'
String 'string'
Number 'number'
Boolean 'boolean'
null 'object'
undefined 'undefined'

alert(typeof NaN) // number

var arr =[1,2,3]
alert(typeof arr) //object

check it with http://dabblet.com/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s