Skip to main content

Most Common Mistakes JavaScript Developers Make

Case Sensitivity
Variables and function names are case sensitive. Like mismatched quotes, you already know this. But, since the error may be silent, here is the reminder. Pick a naming convention for yourself, and stick with it. And, remember that native javascript function and CSS properties in javascript are camelCase.
getElementById('myId') != getElementByID('myId'); // it should be "Id" not "ID"
getElementById('myId') != getElementById('myID'); // "Id" again does not equal"ID"
document.getElementById('myId').style.Color; // returns "undefined"
Mismatching quotes, parenthesis and curly brace
The best way to avoid falling into the trap of mismatched quotes, parentheses and curly brackets is to always code your opening and closing element at the same time, then step into the element to add your code. Start with:
var myString = ""; //code the quotes before entering your string value
function myFunction(){
     if(){   //close out every bracket when you open one.

  }
}

//count all the left parens and right parens and make sure they're equal
alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); //close every parenthesis when a parenthesis is open
Every time you open an element, close it. Put the arguments for a function into the parenthesis after you’ve added the closing parenthesis. If you have a bunch of parenthesis, count the opening parenthesis and then the closing parenthesis, and make sure those two numbers are equal.
Conditional statements (3 gotchas)
  1. All conditional comments must be within parentheses (duh!)
    if(var1 == var2){}
  2. Don’t get tripped up by accidentally using the assignment operator: assigning your second argument’s value to your first argument. Since it’s a logic issue, it will always return true and won’t throw an error.
    if(var1 = var2){} // returns true. Assigns var2 to var1
  3. Javascript is loosely typed, except in switch statements. JavaScript is NOT loosely typed when it comes to case comparisons.
    var myVar = 5;
    if(myVar == '5'){ // returns true since Javascript is loosely typed
      alert("hi");  //this alert will show since JS doesn't usually care about data type.
    }
    switch(myVar){
      case '5':
      alert("hi"); // this alert will not show since the data types don't match
    }
Line Breaks
  • Beware of hard line breaks in JavaScript. Line breaks are interpreted as line-ending semicolons. Even in a string,if you include a hard line break in between quotes you’ll get a parse error (unterminated string).
        var bad  = '
    • some text
    • more text
    '; // unterminated string error var good = '
      ' + '
    • some text
    • ' + '
    • more text
    • ' + '
    '; //correct
  • The line break being interpreted as a semi-colon rule, discussed above, does not hold true in the case of control structures: line breaks after the closing parenthesis of a conditional statement is NOT given a semi-colon.
Always use semi-colons and parenthesis so you don’t get tripped up by breaking lines, so your code is easier to read, and, less thought of but a source of quirks for those who don’t use semicolons: so when you move code around and end up with two statements on one line, you don’t have to worry that your first statement is correctly closed.
Extra commas
The last property in any JavaScript object definition must never end with a comma. Firefox won’t barf on the trailing, unnecessary commas, but IE will.
HTML id conflicts
The JavaScript DOM bindings allow indexing by HTML id. Functions and properties share the same namespace in JavaScript. So, when an id in your HTML has the same name as one of your functions or properties, you can get logic errors that are hard to track down. While this is more of a CSS best practice issue, it’s important to remember when you can’t solve your javascript issue.
var listitems = document.getElementsByTagName('li');

var liCount = listitems.length; // if you have
  • , returns that
  • instead of a count.
  • If you’re marking up (X)HTML, never use a javascript method or property name as the value for an ID. And, when you’re coding the javascript, avoid giving variables names that are ID values in the (X)HTML.
    variable scope
    Many problems in javascript come from variable scope: either thinking that a local variable is global, or overwriting a global variable unwittingly with what should be a local variable in a function. To avoid issues, it’s best to basically not have any global variables. But, if you have a bunch, you should know the “gotchas”.
    Variables that are not declared with the var keyword are global. Remember to declare variables with the var keyterm to keep variables from having global scope. In this example, a variable that is declared within a function has global scope because the var ke
    anonymousFuntion1 = function(){
     globalvar = 'global scope'; // globally declared because "var" is missing.
     return localvar;
    }();
    
    alert(globalvar); // alerts 'global scope' because variable within the function is declared globally
    
    anonymousFuntion2 = function(){
     var localvar = 'local scope'; //locally declared with "var"
     return localvar;
    }();
    
    alert(localvar); // error "localvar is not defined". there is no globally defined localvar
    
    Variable names that are introduced as parameter names are local to the function. There is no conflict if your parameter name is also the name of a global variable as the parameter variable has local scope. If you want to change the global variable from within a function that has a parameter duplicating the global variable’s name, remember that global variables are properties of the window object.
    var myscope = "global";
    
    function showScope(myscope){
      return myscope; // local scope even though there is a global var with same name
    }
    alert(showScope('local'));
    
    function globalScope(myscope){
      myscope = window.myscope; // global scope
      return myscope;
    }
    alert(globalScope('local'));
    
    You should even declare variables within loops
    for(var i = 0; i < myarray.length; i++){}
    string replace
    A common mistake is assuming the behavior of the string replace method will impact all possible matches. Infact, the javascript string replace method only changes the first occurrence. To replace all occurrences, you need to set the global modifier.
      var myString = "this is my string";
      myString = myString.replace(/ /,"%20"); // "this%20is my string"
      myString = myString.replace(/ /g,"%20"); // "this%20is%20my%20string"
    
    parseInt
    The most common error with parding integers in javascript is the assumption that parseInt returns the integer to base 10. Don’t forget the second argument, the radix or base, which can be anything from 2 to 36. To ensure you don’t screw up, always include the second parameter.
    parseInt('09/10/08'); //0parseInt('09/10/08',10); //9, which is most likely what you want from a date.
    ‘this’
    Another common mistake is forgetting to use ‘this‘. Functions defined on a JavaScript object accessing properties on that JavaScript object and failing to use the ‘this’ reference identifier. For example, the following is incorrect:
    function myFunction() {
      var myObject = {
         objProperty: "some text",
         objMethod: function() {
      alert(objProperty);
      }
         };
      myObject.objMethod();
    } 
    
    function myFunction() {
      var myObject = {
         objProperty: "some text",
         objMethod: function() {
      alert(this.objProperty);
      }
         };
      myObject.objMethod();
    }
    There’s an A List Apart article that puts this binding issue into plain English
    Overwriting functions / overloading functions
    When you declare a function more than once, the last declaration of that function will overwrite all previous version of that function throwing no errors or warnings. This is different from other programming languages, like java, where you can have multiple functions with the same name as long as they take different arguments: called function overloading. There is no overloading in javascript. This makes it vitally important to not use the names of core javascript functions in your code. Also, beware of including multiple javascript files, as an included script may overwrite a function in another script. Use anonymous functions and namespaces.
    (function(){
     // creation of my namespace
        // if namespace doesn't exist, create it. if(!window.MYNAMESPACE) {  window['MYNAMESPACE'] = {};   }
    
        // this function only accessible within the anonymous function
        function myFunction(var1, var2){
      //local function code goes here
        }
    
        /* attaches the local function to the namespace
           making it accessible outside of the anoymous function with use of namespace */
        window['MYNAMESPACE']['myFunction'] = myFunction; 
    
     })();// the parenthesis = immediate execution   // parenthesis encompassing all the code make the function anonymous
    Missing Parameters
    A common error is forgetting to update all the function calls when you add a parameter to a function. If you need to add a parameter to handle a special case call in your function that you’ve already been calling, set a default value for that parameter in your function, just in case you missed updating one of the calls in one of your scripts.
    function addressFunction(address, city, state, country){
          country = country || "US"; // if country is not passed, assume USA
          //rest of code
        }
    You can also get the length of the argument array. But we’re focusing on “gotchas” in this post.
    For each
    The “for” loop in javascript will iterate it over all object attributes, both methods and properties, looping thru all of the property names in an object. The enumeration will include all of the properties—including functions and prototype properties that you might not be interested in—so filter out the values you don’t want using hasOwnProperty method and  typeof to exclude functions. Never use for each to iterate thru an array: only use for eachwhen needing to iterated thru object properties and methods.
    • for each (var myVar in myObject) iterates a specified variable over all values of object’s properties.
    • for (var myVar in myObject) iterates a specified variable over all the properties of an object, in arbitrary order. The for...in loop does not iterate over built-in properties. For each distinct property the code is executed
    • for (var 1=0; i < myArray.length; i++) iterates thru all the elements of an array.
    To fix the problem, generally you’ll want to opt for for ... in for objects and use the for loop for arrays:
    listItems = document.getElementsByTagName('li');
    
    for each (var listitem in listItems){
        // this goes thru all the properties and methods of the object,
        // including native methods and properties, but doesn't go thru the array: throws error!
       }
    
    //since you have an array of objects that you are looping thru, use the for loop
    for ( var i = 0; i < listItems.length; i++) {
        // this is what you really wanted
       }
    Switch statements
    I wrote a whole blog post on switch statement quirks, but the gist is:
    • there is no data type conversion
    • once there is a match, all expressions will be executed until the next break or return statement is executed, and
    • you can include multiple cases for a single block of code
    Undefined ≠ null
    Null is for an object, undefined is for a property, method or variable. To be null, your object has to be defined. If your object is not defined, and you test to see whether it’s null, since it’s not defined, it can’t test, and will throw an error.
    if(myObject !== null  && typeof(myObject) !== 'undefined') {
     //if myObject is undefined, it can't test for null, and will throw an error
    }
    
    if(typeof(myObject) !== 'undefined' && myObject !== null) {
     //code handling myObject
    }
    Harish Mallipeddi has an explanation of undefined versus null
    Function location can matter
    There are two ways to declare function: When declaring a function in the form of a variable assignment, location does matter:
    var myFunction = function(arg1, arg2){
      // do something here
    };
    A function declared with
    function myFunction (arg1, arg2){}

    can by used by any code in the file no matter its location (before or after the function declaration). A function declared with the variable assignment syntax can only be used by code that executes after the assignment statement that declares the function.

    Common Mistake #1: Incorrect references to this

    I once heard a comedian say:
    “I’m not really here, because what’s here, besides there, without the ‘t’?”
    That joke in many ways characterizes the type of confusion that often exists for developers regarding JavaScript’s this keyword. I mean, is this really this, or is it something else entirely? Or is it undefined?
    As JavaScript coding techniques and design patterns have become increasingly sophisticated over the years, there’s been a corresponding increase in the proliferation of self-referencing scopes within callbacks and closures, which are a fairly common source of “this/that confusion”.
    Consider this example code snippet:
    Game.prototype.restart = function () {
      this.clearLocalStorage();
      this.timer = setTimeout(function() {
        this.clearBoard();    // what is "this"?
      }, 0);
    };
    
    Executing the above code results in the following error:
    Uncaught TypeError: undefined is not a function
    
    Why?
    It’s all about context. The reason you get the above error is because, when you invoke setTimeout(), you are actually invoking window.setTimeout(). As a result, the anonymous function being passed to setTimeout() is being defined in the context of the window object, which has no clearBoard() method.
    A traditional, old-browser-compliant solution is to simply save your reference to this in a variable that can then be inherited by the closure; e.g.:
    Game.prototype.restart = function () {
      this.clearLocalStorage();
      var self = this;   // save reference to 'this', while it's still this!
      this.timer = setTimeout(function(){
        self.clearBoard();    // oh OK, I do know who 'self' is!
      }, 0);
    };
    
    Alternatively, in newer browsers, you can use the bind() method to pass in the proper reference:
    Game.prototype.restart = function () {
      this.clearLocalStorage();
      this.timer = setTimeout(this.reset.bind(this), 0);  // bind to 'this'
    };
    
    Game.prototype.reset = function(){
        this.clearBoard();    // ahhh, back in the context of the right 'this'!
    };
    

    Common Mistake #2: Thinking there is block-level scope

    As discussed in our JavaScript Hiring Guide, a common source of confusion among JavaScript developers (and therefore a common source of bugs) is assuming that JavaScript creates a new scope for each code block. Although this is true in many other languages, it is not true in JavaScript. Consider, for example, the following code:
    for (var i = 0; i < 10; i++) {
      /* ... */
    }
    console.log(i);  // what will this output?
    
    If you guess that the console.log() call would either output undefined or throw an error, you guessed incorrectly. Believe it or not, it will output 10. Why?
    In most other languages, the code above would lead to an error because the “life” (i.e., scope) of the variable i would be restricted to the for block. In JavaScript, though, this is not the case and the variable i remains in scope even after the for loop has completed, retaining its last value after exiting the loop. (This behavior is known, incidentally, as variable hoisting).
    It is worth noting, though, that support for block-level scopes is making its way into JavaScript through the new let keyword. The let keyword is already available in JavaScript 1.7 and is slated to become an officially supported JavaScript keyword as of ECMAScript 6.
    New to JavaScript? Read up on scopes, prototypes, and more.

    Common Mistake #3: Creating memory leaks

    Memory leaks are almost inevitable JavaScript problems if you’re not consciously coding to avoid them. There are numerous ways for them to occur, so we’ll just highlight a couple of their more common occurrences.
    Memory Leak Example 1: Dangling references to defunct objects
    Consider the following code:
    var theThing = null;
    var replaceThing = function () {
      var priorThing = theThing;  // hold on to the prior thing
      var unused = function () {
        // 'unused' is the only place where 'priorThing' is referenced,
        // but 'unused' never gets invoked
        if (priorThing) {
          console.log("hi");
        }
      };
      theThing = {
        longStr: new Array(1000000).join('*'),  // create a 1MB object
        someMethod: function () {
          console.log(someMessage);
        }
      };
    };
    setInterval(replaceThing, 1000);    // invoke `replaceThing' once every second
    
    If you run the above code and monitor memory usage, you’ll find that you’ve got a massive memory leak, leaking a full megabyte per second! And even a manual GC doesn’t help. So it looks like we are leaking longStr every time replaceThing is called. But why?
    Let’s examine things in more detail:
    Each theThing object contains its own 1MB longStr object. Every second, when we call replaceThing, it holds on to a reference to the prior theThing object in priorThing. But we still wouldn’t think this would be a problem, since each time through, the previously referenced priorThing would be dereferenced (when priorThing is reset via priorThing = theThing;). And moreover, is only referenced in the main body of replaceThing and in the function unused which is, in fact, never used.
    So again we’re left wondering why there is a memory leak here!?
    To understand what’s going on, we need to better understand how things are working in JavaScript under the hood. The typical way that closures are implemented is that every function object has a link to a dictionary-style object representing its lexical scope. If both functions defined inside replaceThing actually used priorThing, it would be important that they both get the same object, even if priorThing gets assigned to over and over, so both functions share the same lexical environment. But as soon as a variable is used by any closure, it ends up in the lexical environment shared by all closures in that scope. And that little nuance is what leads to this gnarly memory leak. (More detail on this is available here.)
    Memory Leak Example 2: Circular references
    Consider this code fragment:
    function addClickHandler(element) {
        element.click = function onClick(e) {
            alert("Clicked the " + element.nodeName)
        }
    }
    
    Here, onClick has a closure which keeps a reference to element (via element.nodeName). By also assigning onClick to element.click, the circular reference is created; i.e.: element -> onClick -> element -> onClick -> element
    Interestingly, even if element is removed from the DOM, the circular self-reference above would prevent element and onClick from being collected, and hence, a memory leak.
    Avoiding Memory Leaks: What you need to know
    JavaScript’s memory management (and, in paticular, garbage collection) is largely based on the notion of object reachability.
    The following objects are assumed to be reachable and are known as “roots”:
    • Objects referenced from anywhere in the current call stack (that is, all local variables and parameters in the functions currently being invoked, and all the variables in the closure scope)
    • All global variables
    Objects are kept in memory at least as long as they are accessible from any of the roots through a reference, or a chain of references.
    There is a Garbage Collector (GC) in the browser which cleans memory occupied by unreachable objects; i.e., objects will be removed from memory if and only if the GC believes that they are unreachable. Unfortunately, it’s fairly easy to end up with defunct “zombie” objects that are in fact no longer in use but that the GC still thinks are “reachable”.

    Common Mistake #4: Confusion about equality

    One of the conveniences in JavaScript is that it will automatically coerce any value being referenced in a boolean context to a boolean value. But there are cases where this can be as confusing as it is convenient. Some of the following, for example, have been known to bite many a JavaScript developer:
    // All of these evaluate to 'true'!
    console.log(false == '0');
    console.log(null == undefined);
    console.log(" \t\r\n" == 0);
    console.log('' == 0);
    
    // And these do too!
    if ({}) // ...
    if ([]) // ...
    
    With regard to the last two, despite being empty (which might lead one to believe that they would evaluate to false), both {} and [] are in fact objects and any object will be coerced to a boolean value of truein JavaScript, consistent with the ECMA-262 specification.
    As these examples demonstrate, the rules of type coercion can sometimes be clear as mud. Accordingly, unless type coercion is explicitly desired, it’s typically best to use === and !== (rather than == and !=), so as to avoid any unintended side-effects of type coercion. (== and != automatically perform type conversion when comparing two things, whereas === and !== do the same comparison without type conversion.)
    And completely as a sidepoint – but since we’re talking about type coercion and comparisons – it’s worth mentioning that comparing NaN with anything (even NaN!) will always return false.  You therefore cannot use the equality operators (=====!=!==) to determine whether a value is NaN or not. Instead, use the built-in global isNaN() function:
    console.log(NaN == NaN);    // false
    console.log(NaN === NaN);   // false
    console.log(isNaN(NaN));    // true
    

    Common Mistake #5: Inefficient DOM manipulation

    JavaScript makes it relatively easy to manipulate the DOM (i.e., add, modify, and remove elements), but does nothing to promote doing so efficiently.
    A common example is code that adds a series of DOM Elements one at a time. Adding a DOM element is an expensive operation. Code that adds multiple DOM elements consecutively is inefficient and likely not to work well.
    One effective alternative when multiple DOM elements need to be added is to use document fragmentsinstead, thereby improving both efficiency and performance.
    For example:
    var div = document.getElementsByTagName("my_div");
    
    var fragment = document.createDocumentFragment();
    
    for (var e = 0; e < elems.length; e++) {  // elems previously set to list of elements
        fragment.appendChild(elems[e]);
    }
    div.appendChild(fragment.cloneNode(true));
    
    In addition to the inherently improved efficiency of this approach, creating attached DOM elements is expensive, whereas creating and modifying them while detached and then attaching them yields much better performance.

    Common Mistake #6: Incorrect use of function definitions inside for loops

    Consider this code:
    var elements = document.getElementsByTagName('input');
    var n = elements.length;    // assume we have 10 elements for this example
    for (var i = 0; i < n; i++) {
        elements[i].onclick = function() {
            console.log("This is element #" + i);
        };
    }
    
    Based on the above code, if there were 10 input elements, clicking any of them would display “This is element #10”! This is because, by the time onclick is invoked for any of the elements, the above for loop will have completed and the value of i will already be 10 (for all of them).
    Here’s how we can correct the above code problems, though, to achieve the desired behavior:
    var elements = document.getElementsByTagName('input');
    var n = elements.length;    // assume we have 10 elements for this example
    var makeHandler = function(num) {  // outer function
         return function() {   // inner function
             console.log("This is element #" + num);
         };
    };
    for (var i = 0; i < n; i++) {
        elements[i].onclick = makeHandler(i+1);
    }
    
    In this revised version of the code, makeHandler is immediately executed each time we pass through the loop, each time receiving the then-current value of i+1 and binding it to a scoped num variable. The outer function returns the inner function (which also uses this scoped num variable) and the element’s onclick is set to that inner function. This ensures that each onclick receives and uses the proper i value (via the scoped num variable).

    Common Mistake #7: Failure to properly leverage prototypal inheritance

    A surprisingly high percentage of JavaScript developers fail to fully understand, and therefore to fully leverage, the features of prototypal inheritance.
    Here’s a simple example. Consider this code:
    BaseObject = function(name) {
        if(typeof name !== "undefined") {
            this.name = name;
        } else {
            this.name = 'default'
        }
    };
    
    Seems fairly straightforward. If you provide a name, use it, otherwise set the name to ‘default’; e.g.:
    var firstObj = new BaseObject();
    var secondObj = new BaseObject('unique');
    
    console.log(firstObj.name);  // -> Results in 'default'
    console.log(secondObj.name); // -> Results in 'unique'
    
    But what if we were to do this:
    delete secondObj.name;
    
    We’d then get:
    console.log(secondObj.name); // -> Results in 'undefined'
    
    But wouldn’t it be nicer for this to revert to ‘default’? This can easily be done, if we modify the original code to leverage prototypal inheritance, as follows:
    BaseObject = function (name) {
        if(typeof name !== "undefined") {
            this.name = name;
        }
    };
    
    BaseObject.prototype.name = 'default';
    
    With this version, BaseObject inherits the name property from its prototype object, where it is set (by default) to 'default'. Thus, if the constructor is called without a name, the name will default to default. And similarly, if the name property is removed from an instance of BaseObject, the prototype chain will then be searched and the name property will be retrieved from the prototype object where its value is still 'default'. So now we get:
    var thirdObj = new BaseObject('unique');
    console.log(thirdObj.name);  // -> Results in 'unique'
    
    delete thirdObj.name;
    console.log(thirdObj.name);  // -> Results in 'default'
    

    Common Mistake #8: Creating incorrect references to instance methods

    Let’s define a simple object, and create and instance of it, as follows:
    var MyObject = function() {}
    
    MyObject.prototype.whoAmI = function() {
        console.log(this === window ? "window" : "MyObj");
    };
    
    var obj = new MyObject();
    
    Now, for convenience, let’s create a reference to the whoAmI method, presumably so we can access it merely by whoAmI() rather than the longer obj.whoAmI():
    var whoAmI = obj.whoAmI;
    
    And just to be sure everything looks copacetic, let’s print out the value of our new whoAmI variable:
    console.log(whoAmI);
    
    Outputs:
    function () {
        console.log(this === window ? "window" : "MyObj");
    }
    
    OK, cool. Looks fine.
    But now, look at the difference when we invoke obj.whoAmI() vs. our convenience reference whoAmI():
    obj.whoAmI();  // outputs "MyObj" (as expected)
    whoAmI();      // outputs "window" (uh-oh!)
    
    What went wrong?
    The headfake here is that, when we did the assignment var whoAmI = obj.whoAmI;, the new variable whoAmI was being defined in the global namespace. As a result, its value of this is windownot the objinstance of MyObject!
    Thus, if we really need to create a reference to an existing method of an object, we need to be sure to do it within that object’s namespace, to preserve the value of this. One way of doing this would be, for example, as follows:
    var MyObject = function() {}
    
    MyObject.prototype.whoAmI = function() {
        console.log(this === window ? "window" : "MyObj");
    };
    
    var obj = new MyObject();
    obj.w = obj.whoAmI;   // still in the obj namespace
    
    obj.whoAmI();  // outputs "MyObj" (as expected)
    obj.w();       // outputs "MyObj" (as expected)
    

    Common Mistake #9: Providing a string as the first argument to setTimeout or setInterval

    For starters, let’s be clear on something here: Providing a string as the first argument to setTimeout or setInterval is not itself a mistake per se. It is perfectly legitimate JavaScript code. The issue here is more one of performance and efficiency. What is rarely explained is that, under the hood, if you pass in a string as the first argument to setTimeout or setInterval, it will be passed to the function constructor to be converted into a new function. This process can be slow and inefficient, and is rarely necessary.
    The alternative to passing a string as the first argument to these methods is to instead pass in a function. Let’s take a look at an example.
    Here, then, would be a fairly typical use of setInterval and setTimeout, passing a string as the first parameter:
    setInterval("logTime()", 1000);
    setTimeout("logMessage('" + msgValue + "')", 1000);
    
    The better choice would be to pass in a function as the initial argument; e.g.:
    setInterval(logTime, 1000);   // passing the logTime function to setInterval
    
    setTimeout(function() {       // passing an anonymous function to setTimeout
        logMessage(msgValue);     // (msgValue is still accessible in this scope)
      }, 1000);
    

    Common Mistake #10: Failure to use “strict mode”

    As explained in our JavaScript Hiring Guide, “strict mode” (i.e., including 'use strict'; at the beginning of your JavaScript source files) is a way to voluntarily enforce stricter parsing and error handling on your JavaScript code at runtime, as well as making it more secure.
    While, admittedly, failing to use strict mode is not a “mistake” per se, its use is increasingly being encouraged and its omission is increasingly becoming considered bad form.
    Here are some key benefits of strict mode:
    • Makes debugging easier. Code errors that would otherwise have been ignored or would have failed silently will now generate errors or throw exceptions, alerting you sooner to problems in your code and directing you more quickly to their source.
    • Prevents accidental globals. Without strict mode, assigning a value to an undeclared variable automatically creates a global variable with that name. This is one of the most common errors in JavaScript. In strict mode, attempting to do so throws an error.
    • Eliminates this coercion. Without strict mode, a reference to a this value of null or undefined is automatically coerced to the global. This can cause many headfakes and pull-out-your-hair kind of bugs. In strict mode, referencing a a this value of null or undefined throws an error.
    • Disallows duplicate property names or parameter values. Strict mode throws an error when it detects a duplicate named property in an object (e.g., var object = {foo: "bar", foo: "baz"};) or a duplicate named argument for a function (e.g., function foo(val1, val2, val1){}), thereby catching what is almost certainly a bug in your code that you might otherwise have wasted lots of time tracking down.
    • Makes eval() safer. There are some differences in the way eval() behaves in strict mode and in non-strict mode. Most significantly, in strict mode, variables and functions declared inside of an eval()statement are not created in the containing scope (they are created in the containing scope in non-strict mode, which can also be a common source of problems).
    • Throws error on invalid usage of delete. The delete operator (used to remove properties from objects) cannot be used on non-configurable properties of the object. Non-strict code will fail silently when an attempt is made to delete a non-configurable property, whereas strict mode will throw an error in such a case.
    Memory Leaks:  Memory leaks can be terms as the memory that is not used by the application anymore and still not returned back to the pool of free memory. Different languages have different memory management system that helps them to heed the garbage memory.
    Generally, it is a common problem that most of the developers don’t have an idea that, memory management can be handled on developers end. While writing the code, the developer can inform the program whether the value is occupied or is free. If you are creating a web application for a university comparison website or a limited company with quality formations then you should work carefully on Javascript.
    JavaScript is one of the garbage collected languages.  Garbage collected languages are those which allows the developer to manage its memory, resulting in effective memory management.
    In JavaScript, the garbage collection is done in form of “roots”. These roots are the global variables which are used to store the references within the code. Mark and Sweep algorithm is used to control the memory. The algorithm marks the roots that are being used, as active.
    Simultaneously, the roots which are left inactive will be available for use again.
    If Else Error: This concept is used when you want the program to respond to every occurrence of the answer. Like for example, “==” and “=” are to misconceptions that developers normally find.
    These types of typo errors must be avoided prior to moving on the final coding section. Generally, these types of test can arrive on social media.
    JavaScript Closure:  Closure in JavaScript is defined as the nested function that uses the parent function’s variable. It can also be defined as the function in which has the command on three types of variables i.e.
    • A variable declared within the function
    • A variable declared in the parent function
    • A global variable that is accessible to all
    To deal with these issues, the developers are generally prescribed to avoid making unnecessary nested functions. Solving this issue will not only make your code closure free, but it will also deal with the memory allocation problem.
    Whenever you are creating a new object or class, always consider associating the methods with the object's prototype instead of defining it in the object’s constructor.
    Undefined vs NULL: Well, this issue occurs with the newcomers who don’t know the difference between the undefined and NULL value. In other programming languages, it is easy to set NULL value to the variables. However, in JavaScript, by default, the variables are set to undefined and objects are set to NULL. For an object to be NULL, it must be initially defined by the coder.
    Following are some points that you must be aware of:
    undefined == null //true
    undefined === null //false
    typeof null //”object” should have returned null. If it’s an object, what about adding few properties
    typeof undefined //”undefined”
    The above-mentioned bugs are a few that a JS developer generally neglects while coding for a script. These issues seem to be minor, but it causes a big loss of your memory, code structure. It also generates loopholes that make it easy to breach the code.
    So, next time you write a script of code, always remember the points mentioned above. Remember that these are not the only mistakes that a code does. Instead, there are many other which should be avoided to get a bug free script.

    Some people (and jshint in its default state) will get all uppity about variable declaration in JavaScript, and the supposedly mandatory nature of semicolons. But seriously, which looks more readable to you?
    var Thing = require('thing'),
        thing = new Thing(),
        stuff = thing.whatsit();
    
    stuff.doStuff(function(err){
      if (err) console.log(err);
      else console.log('done');
    })    
    
    vs
    var Thing = require('thing')
    var thing = new Thing()
    var stuff = thing.whatsit()
    
    stuff.doStuff(function(err){
      if (err) console.log(err)
      else console.log('done')
    })    
    
    The reality is that:
    1. Extra var declarations don't slow your code down (Don't believe me? Compare test1 - 0.536 seconds to test2 - 0.533 seconds and see for yourself. They each take essentially the same amount of time to run.)
    2. Semicolons and carriage returns serve the same purpose in JavaScript. You only need semicolons if you are concatenating code together in a single line.
    3. Consistency and readability are important tools in your code quality utility belt.
    Consider the following piece of code:
    function doStuff(thing) {
      var whatsit = new Whatsit(thing);
          stuff = new Stuff(whatsit);
    
      // do stuff with stuff
    
      return stuff
    }
    
    In the above example the variable stuff is a global-scope variable, and not local to the function. That error can be very hard to spot in a busy codebase.
    Your slavish adherence to superstitious nonsense is forcing you to have to remember to replace the semicolon with a comma, and add the semi-colon to the end. And if you forget, it's not going to throw up an error, but your stuff will not be in the same scope as your thing, or whatsit, (without the var it will probably get promoted up to being a global variable, with possibly nasty (and hard to spot) consequences.
    Better to just throw the variable declaration in there with a var in front of it like the other lines.
    function doStuff(thing) {
      var whatsit = new Whatsit(thing)
      var stuff   = new Stuff(whatsit)
    
      // do stuff with stuff
    
      return stuff
    }
    
    The lines now all look the same, and there's no chance of accidentally promoting a variable to global-scope.

    2 Return before asynchronous callbacks have completed

    Here's something I see every day. It's an easy mistake to make, and affects both server-side Node.JS and client-side developers alike.
    Consider the following pretty typical Express or Sails.JS style controller function.
    var myFunction = function(req, res) {
      User.findOne({name: req.body.name}).exec(function(err, user){
        if (err) return res.json(400, err)
        user.update({description: req.body.description}).exec(function(err, user){
          if (err) return res.json(400, err)
        })
        return res.json(user)
      })
    }
    
    Putting the return res.json(user) outside of the update's callback is an easy mistake to make, and the view from an AJAX call at the other end will only see a userthat has not been updated.
    But the user has been updated, just not before your function returns. Moving the final return up into update's callback makes a world of difference.
    var myFunction = function(req, res) {
      User.findOne({name: req.body.name}).exec(function(err, user){
        if (err) return res.json(400, err)
        user.update({description: req.body.description}).exec(function(err, user){
          if (err) return res.json(400, err)
          return res.json(user)
        })
      })
    }
    
    A similar error I often see on the client end is:
    var thing = null
    var thingId = $("#thing-id").val()
    $.get("/thing/" + thingId, function(data){
      thing = data.thing
      console.log("got thing", thing)
    }).fail(function(err){
      console.log("got error", err)
    })
    $(".thing-name").text(thing)
    
    The issue here is that $(".thing-name").text(thing) is being executed before the data is retrieved from the server, and so thing is still null.
    The correct thing to do is:
    var thingId = $("#thing-id").val()
    $.get("/thing/" + thingId, function(data){
      console.log("got thing", data.thing)
      $(".thing-name").text(data.thing)
    }).fail(function(err){
      console.log("got error", err)
    })
    
    Another case where JavaScript developers get caught up dealing with asynchronous calls is when you need you have a number of parallel, time consuming services that need to be run, and you need to collate the results.
    Say for example you need to query two different APIs and combine the results.
    I've seen people write this:
    function thingyWhatsit(thingId, whatsitId) {
      var thingData = null
      var whatsitData = null
      $.get("/thing/" + thingId, function(data){
        thingData = data
      }).fail(function(err){
        console.log("got thing error", err)
      })
      $.get("/whatsit/" + whatsitId, function(data){
        whatsitData = data
      }).fail(function(err){
        console.log("got whatsit error", err)
      })
      return $.extend(true, {}, thingData, whatsitData)
    }
    
    // assume tid and wid come from somewhere
    var result = thingyWhatsit(tid, wid)
    
    This is obviously wrong as neither the thingData or whatsitData will have been retrieved by the time the return is called, so the function will always return {}
    It's tempting to go:
    function thingyWhatsit(thingId, whatsitId) {
      $.get("/thing/" + thingId, function(thingData){
        $.get("/whatsit/" + thingId, function(whatsitData){
          return $.extend(true, {}, thingData, whatsitData)
        }).fail(function(err){
          console.log("got inner error", err)
        })
      }).fail(function(err){
        console.log("got error", err)
      })
    }
    
    // assume tid and wid come from somewhere
    var result = thingyWhatsit(tid, wid)
    
    That will work, but it's forcing the second call to wait for the first call to complete which is entirely inefficient.
    A better solution is to use a third-party library such as asyncasync allows you to write the above like this:
    function thingyWhatsit(thingId, whatsitId, callback) {
      async.parallel({
        thing: function(next) {
          $.get("/thing/" + thingId, function(data){
            next(null, data)
          }).fail(function(err){
            next(err, null)
          })
        },
        whatsit: (function(id) {
          $.get("/whatsit/" + whatsitId, function(data){
            next(null, data)
          }).fail(function(err){
            next(err, null)
          })
        }
      }, function(result) {
        if (result.err) {
          callback({errors: result.err}, null)
        } else {
          callback(null, $.extend(true, {}, result.thing, result.whatsit)
        }
      })
    }
    
    // assume tid and wid come from somewhere
    var result = thingyWhatsit(tid, wid)
    
    This will fire off each AJAX query in parallel, and if either has errors, will return a summary of the errors, or, if there are no errors, it will correctly combine the results.
    Libraries like async are powerful tools, and the most useful ones work on both client- and server-side.
    Try the JavaScript drinking game. Think of a word, add 'js' to it, and Google it. If there is a {word}js package then drink.

    3 Fail to notice that = is not ==

    Here's something that I see frighteningly often that can really mess up your day:
    var x = someFunction()
    
    if (x = 'hello world') console.log("winning!", x)
    else console.log("Dammit Chloe!", x)
    
    No matter what someFunction() returns, you'll always see "winning! hello world" because that x = 'hello world' is an assignment and not a comparison.
    It's a terribly easy mistake to make, when you should have written:
    var x = someFunction()
    
    if (x == 'hello world') console.log("winning!", x)
    else console.log("ammit Chloe!," x)
    
    Likewise, sometimes a developer will write:
    var i == 10
    
    The JavaScript interpreter will flag that as a syntax error; but what about if you've done this:
    function check(item, callback) {
      var item = new Item(),
          thing = new Thing(item),
          whatsit = New Wahtsit(thing),
          check_item = null;
    
    // some code that does stuff
    for (var i = 0, l = items.length; i++) {
      check_item == items[i];
      setTimeout(function() {
        do_some_complex_stuff_with_checked_item();
        callback(check_item);
      }, 0);
    }
    
    Here the check_item == items[i]; line simply evaluates to false and check_itemis never assigned. The consequence here might be that the item you thought was being checked, is not being checked at all, and so items with errors ended up in your datastore. Data integrity issues can be hard to catch early enough that they don't do damage

    4 Forget that == isn't the same as === (&& !=isn't the same as !==)

    Related to point 3 above, there's a world of difference between == a value comparison, and === which compares object references.
    var x = someFunctionThatReturnsAnObject()
    var y = someFunctionThatReturnsAnObject()
    
    if (x == y) console.log("same same", x, y)
    else console.log("different", x, y)
    
    will likely show "same same [object] [object]", whereas
    var x = someFunctionThatReturnsAnObject()
    var y = someFunctionThatReturnsAnObject()
    
    if (x === y) console.log("same same", x, y)
    else console.log("different", x, y)
    
    will always show "different [object] [object]" if x and y are not the same objects.
    Note: when comparing something to null, it's considered more appropriate to use === or !==.

    5 Use & when they mean to use &&

    The 'bitwise' & is used to compare Integers, and if the values being compared are not Integers, they are coerced into Integers. The standard && is used to compare the truthiness of the operands.
    So 123 & false === 0 (because the false becomes a 0) but 123 && false === false 9 & 5 === 1 but 9 && 5 === 5.
    But why does 9 && 5 === 5 and not equal true?
    Because the && is a chaining operator, meaning it passes its value along until the final value is needed. In this example the 9 is truthy, and so this is like saying true && 5 which evaluates to 5. This is really useful if you want to do something like: var x = req.body && req.body.name && doSomething(req.body.name). If req.body is null, or req.body.name is null, then doSomething(req.body.name) will never be evaluated.
    Alternatively, 9 & 5 === 1 because the & operator compares the bits of each number and returns the anded result of each bit.
    9 decimal is  1001 binary, 5 decimal is  0101 binary, so 5 & 9 is thus 0001 binary, which is 1.

    6 Use | when they mean to use ||

    Similarly, it's easy to get confused between the bitwise | and the logical ||.
    9 | 5 === 13 (using similar logic to the above & operator, but oring the bits instead of anding them), wheras 9 || 5 === 9 (because the 9 is truthy, and so evaluation of the expression stops there.)

    7. Forget that |= in JavaScript is nothing like ||=in Ruby

    Another thing that can confuse web developers flipping between Ruby and JavaScript is |= vs ||=.
    Again, it's an easy typo to make, and can generate hard-to-spot and unexpected results.
    In Ruby,
    x = some_thing_maybe_nil
    # ... later on in the code
    x ||= 5
    
    is perfectly reasonable, and, if x was nil then x becomes 5 and on we roll, and if x was 9 then x will remain 9.
    But in JavaScript,
    var x = some_thing_maybe_null()
    // ... later on in the code
    x |= 5
    
    will either:
    1. Throw an error if x === null, or;
    2. Give you 13 if x === 9.
    The former is obviously easy to spot. The latter is very hard.

    8 Mistake null (in JavaScript) for nil (in Ruby) and vice-versa

    Ruby developers will be familiar with the idea that nil is what JavaScript developers call null. Ruby developers often switch between Ruby and JavaScript when developing websites, and so I see this error creep in a lot.
    var x = nil will give x the value undefined, not null and spotting that can be hard sometimes.

    9 Fail to notice that this is not always this

    This looks right eh? But don't be fooled. The this in the anonymous function called by setTimeout is not the same this as in the Thing function.
    function Thing(name) {
      this.name = name
    }
    Thing.prototype.delayedName = function(callback){
      setTimeout(function() {
        callback(this.name)
      }, 1000)
    }
    var thing = new Thing('whatsit')
    thing.delayedName(function(name){
      console.log("clicked", name.toUpperCase())
    })
    
    Running the above code will cause it to fail with Uncaught TypeError: undefined is not a function.
    To get around this you might be tempted to to try:
    function Thing(name) {
      this.name = name
      var that = this
      this.delayedName = function(callback){
        setTimeout(function() {
          callback(that.name.toUpperCase())
        }, 1000)
      }
    }
    var thing = new Thing('whatsit')
    thing.delayedName(function(name){
      console.log("clicked", name.toUpperCase())
    })
    
    which will work at first, but keep doing it and you'll leak memory and kill your app, or your user's browser. Why? Well, the reference to that never gets properly released, and eventually builds up into a zombie-reference apocalypse.
    Also by attaching the function directly to this.delayedName you are binding it to the instance and not to the function itself. This is typically not a problem, but it's not efficient either, and you run the risk of someone going
    var thing      = Thing('hello')
    var otherThing = Thing('goodbye')
    otherThing.delayedName = function(){}
    
    in which case thing.delayedName() and otherThing.delayedName() will exhibit different behaviours.
    To achieve the goal you want here you need to use closures, which leverage JavaScript's natural way of creating anonymous functions, and be sure to use JavaScript's prototype function to bind the method to the function definition itself, and not to each instance individually.
    function Thing(name) {
      this.name = name
    }
    Thing.prototype.delayedName = function(callback) {
      setTimeout((function(that) {
        function() {
          callback(that.name);
        };
      })(this), 1000);
    };
    
    var thing = new Thing('whatsit')
    thing.delayedName(function(name){
      console.log("clicked", name.toUpperCase())
    })
    
    By passing this in, and allowing it to be assigned to the paramater that, we avoid the memory leaks, and keep this in scope.

    10 Thinking that variables can be scoped to their blocks

    Unlike many other languages, JavaScript considers a variable "in scope" if it has seen it.
    So this works:
    var i = 0
    for (var ii = 0; ii < 9; ii++){
      i += 1
    }
    console.log("i = ", i)
    
    with the result i = 10.
    And this works (and without without leaking memory, per point #9 above):
    function delay(seconds, message) {
      setTimeout((function(startTime){
        var duration = (new Date() - startTime) / 1000.0
        console.log("delay of ", seconds, "for message", message, "actually took", duration, "seconds" )
      })(new Date()), seconds)
    }
    
    But this won't work:
    function add(firstNumber, secondNumber) {
      var i = firstNumber + secondNumber
    }
    
    add(7, 666)
    console.log("i =", i)
    
    i will always be undefined in that case.
    If you declare a variable at the top level of your client-side script, it will effectively become a global variable, and this is generally frowned upon, as there might be a chance that you'll accidentally overwrite other scripts' variables if they also shoved things in the global scope.
    Better practice is to contain your entire script within a closure, and pass in core elements like the document and window objects, and jQuery (and/or whichever frameworks, libraries, etc. your script might wish to call upon)
    (function($, document, undefined){
      // do stuff
    })(jQuery, document)
    
    There are two core benefits to this. One is it allows you to test variables against undefined.
    if ($ === undefined || document === undefined) throw "Dammit! Chloe"
    
    will work within the above closure, which looks better than:
    if (typeof $ === 'undefined' || typeof document === 'undefined') throw "Dammit! Chloe"
    
    or:
    if ($ === void 0 || document === void 0) throw "Dammit! Chloe"
    
    each of which do the same thing.
    The second reason is that it's faster. JavaScript looks for variables by searching back up through the tree-structure of the code, starting with the immediate local scope and working up through the stack, until it reaches the global scope. Because the document and $ variables don't need to be sourced from the global scope, but are immediately available as parameters, the JavaScript interpreter often has much less work to do.
    The third reason is that using closures isolates your variables from the global scope, and thus avoids any chance of a clash with other plugins, frameworks, and so forth. Such conflicts are the cause of many difficult-to-debug errors.
    Finally, the other consequence of the way JavaScript sees variables means that order matters when you include scripts in your web page. For example you must load jQuery before you load Bootstrap.

    11 Keep on using JavaScript when there's Coffeescript

    Coffeescript is awesome. It makes writing JavaScript so much simpler, and far less error prone. Almost every single error case outlined above is close to impossible to mess up in Coffeescript.
    Take the this vs that issue in #9 above.
    To write the equivalent code in Coffeescript, you'd write
    class Thing
      constructor: (@name) ->
      delayedName: (callback) ->
        setTimeout =>
          callback @name
        , 1000
    
    
    thing = new Thing('whatsit')
    thing.delayedName (name) ->
      console.log name.toUpperCase()
    
    In Coffeescript @ is a reference to this. Note the use of => vs ->. The fattie, as it's lovingly known, tells Coffeescript to repoint @ to a copy of this (called _thistypically) that's passed in via an auto-generated closure. Cofeescript will also generate the prototype code for you properly.
    There's no need to use && or == etc in Coffeescript, you can use the reserved words orandnotis and isnt. You can also use unless as an alternative to if if that helps with readability.
    x = 10 if x is undefined is perfectly valid, and wonderfully readable Coffeescript.
    Coffeescript lets you use strings as Ruby does, so:
    (message) ->
      console.log "MESSAGE: #{message}"
    
    is perfectly valid. Watch out if you use HAML and write your scripts inline. The "#{message}" bit will be evaluated as Ruby and not as Coffeescript. Slim does not have this limitation.
    There are all sorts of other cool things that Coffeescript lets you do that are complicated and error-prone to do in JavaScript.
    Consider doSomething(thing) for thing in list_of_things when thing.name is 'Brian'
    The same thing in JavaScript is more like:
    for (var i = 0; i < list_of_things.length; i++) {
      var thing = list_of_things[i];
      if (thing.name === 'Brian') {
        doSomething(thing);
      }
    }
    
    Similarly Coffeescript lets you do things_named_brian = (thing for thing in things when thing.name is 'Brian')
    which in Javscript is more like:
    var things_named_brian = []
    for (var i = 0; i < things.length; i++) {
      var thing = things[i]
      if (thing.name === 'Brian') {
        things_named_brian.push(thing)
      }
    }
    
    I know which one I'd rather write. And read. And debug.
    Coffeescript also automatically generates a higher-order closure for you if you don't.
    So:
    messages = ['hello', 'dolly']
    console.log(message) for message in messages
    
    is actually extracted to:
    (function(){
      var messages, _i, _l;
      messages = ['hello', 'dolly'];
      for (i = 0, l = messages.length; i < l; i++) {
       console.log(messages[i]);
      }
    })();
    
    which is wonderfully, formally, correct, but kinda ugly.
    Coffeescript already predefines undefined for you too. So: 
    throw "Dammit! Chloe" if $ is undefined or document is undefined
    
    is perfectly valid.
    Coffeescript has the same core scoping rules as JavaScript, but helps you with automatic closures, enforced local variable declarations (nothing goes into the global scope unless you put it there specifically), and the ability to coordinate their use by means of the => vs the -> symbol.
    While Coffeescript will guard you against many of the above errors, it won't help you much with your own errors, and its terse nature can be a source of other bugs. It won't help you much with logic bombs, other than being nicer to look at and so, easier to understand. It does also give you formal class structures, and generates all that annoying Model.prototype.doStuff = function() stuff for you.
    Debugging the JavaScript generated by Coffeescript can be very hard to do. Sourcemaps can help with this, but only in a browser. Debugging the JavaScript that Coffeescript generates in a Node.JS contex is often very difficult.

    https://www.w3schools.com/js/js_mistakes.asp

    Comments

    Popular posts from this blog

    A Journey to Italy

    Well, Last week i had a journey to Italy. I have visited Venice few months ago but not the Rome. Hopefully weather was great and i tried to see all Rome's highlights in 3 days. here are some info and pictures : Altare della Patria (Vittoriano) The  Altare della Patria  (Altar of the Fatherland) also known as the  Monumento Nazionale a Vittorio Emanuele II  (National Monument to Victor Emmanuel II) or  "Il Vittoriano"  is a monument built in honour of  Victor Emmanuel , the first king of a unified Italy, located in  Rome ,  Italy . It occupies a site between the  Piazza Venezia  and the  Capitoline Hill . The  eclectic   structure  was designed by  Giuseppe Sacconi  in 1885; sculpture for it was parceled out to established sculptors all over Italy, such as  Leonardo Bistolfi  and  Angelo Zanelli . [1]  It was inaugurated in 1911 and completed in 1925. Colosseum The...

    BMW's Laser Headlights

    BMW Laser Lights Explained First time introduced Adaptive Lights on BMW 7 series, 2012 New Laser Lights on BMW i8