Key Javascript concepts with examples

Key Javascript concepts (and examples) that I have found important/foundational and which have helped me put things in perspective while studying JavaScript libraries vs. JavaScript frameworks
  • Variable scope
    In JavaScript, objects and functions, are also variables.
    In JavaScript, scope is the set of variables, objects, and functions you have access to.
    JavaScript has function scope: The scope changes inside functions.
    
    
    LOCAL
    // code here can not use carName
    function myFunction() {
         var carName = "Volvo";
         // code here can use carName
    }
     
    GLOBAL
    var carName = " Volvo";
    // code here can use carName
    function myFunction() {
         // code here can use carName
    }
     
    AUTOMATICALLY GLOBAL
    // code here can use carName
    function myFunction() {
         carName = "Volvo";
        // code here can use carName
    }
     
    // If running in browser code here can use window.carName
    function myFunction() {
         carName = "Volvo";
    }
    

    reference: http://www.w3schools.com/js/js_scope.asp

  • Javascript Object
    var person = {
            firstName:"John",
            lastName:"Doe",
            age:50,
            eyeColor:"blue",
            fullName : (function () {return this.firstName+" "+this.lastName;})}
    console.log("person.fullName:"+person.fullName())
    QUESTION: Why is person.fullName not returing a function? Why is it printing the returned value?
    

    reference: http://speakingjs.com/es5/ch16.html

  • Lexical scoping (static/compile-time) Scope of name binding and how the validity of binding is determined: statically or dynamically
    console.log("Running lexical scoping example:");
    function init() {
      var name = "Mozilla1"; // name is a local variable created by init
      function displayName() { // displayName() is the inner function, a closure
        console.log(name); // use variable declared in the parent function   
      }
      displayName();   
    }
    init();
    

    Lexical vs dynamic scope

    x=1
    function g () { echo $x ; x=2 ; }
    function f () { local x=3 ; g ; }
    f # does this print 1, or 3?
    echo $x # does this print 1, or 2?
    

    So, what exactly does this program print? It depends on the scoping rules. If the language of this program is one that uses lexical scoping, then g prints and modifies the global variable x (because g is defined outside f), so the program prints 1 and then 2. By contrast, if this language uses dynamic scoping, then g prints and modifies f’s local variable x (because g is called from within f), so the program prints 3 and then 1

  • The context of “this”
    var Person = {
      name: "Tim",
      age: 28,
      greeting: function () {
        return "Hello " + this.name + ".  Wow, you are " + this.age + " years old.";
      }
    };
    Person.greeting();
     
    var greeting = Person.greeting;
    greeting(); // Will get undefined for `this.name` and `this.age`
     
    var Dog = {
      name: "Alfred",
      age: 110,
      greeting: Person.greeting
    }
     
    Dog.greeting(); // This will work and it will show the dog's data.
    

    binding “this”

    Cart = {  items: [1,4,2], 
                    onClick: function () {   
                            // Do something with this.items. 
                            }}
    $("#mybutton").click(Cart.onClick); //event is bound to onClick and this = Cart is not true at runtime...
     
    one of the solutions: create a Closure
    $("#mybutton").click(function () { Cart.onClick() });
    

    reference: http://howtonode.org/what-is-this
    reference: http://www.sitepoint.com/what-is-this-in-javascript/

  • Closure
    console.log("Running closure example:");
    function makeFunc() {
      var name = "Mozilla2";
      function displayName() {
        console.log(name);
      }
      return displayName;
    }
    var myFunc = makeFunc();
    myFunc();
    

    The code still works may seem unintuitive. Normally, the local variables within a function only exist for the duration of that function’s execution. Once makeFunc() has finished executing, it is reasonable to expect that the name variable will no longer be accessible. Since the code still works as expected, this is obviously not the case. The solution to this puzzle is that myFunc has become a closure. A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created. In this case, myFunc is a closure that incorporates both the displayName function and the “Mozilla” string that existed when the closure was created.

    function makeAdder(x) {
      return function(y) {
        return x + y;
      };
    }
     
    var add5 = makeAdder(5);
    var add10 = makeAdder(10);
     
    console.log("add5(2):"+add5(2));  // 7
    console.log("add10(2):"+add10(2)); // 12
    

    closures in a loop

    Your e-mail address

    E-mail:
    Name:
    Age:

    function showHelp(help) {
      document.getElementById('help').innerHTML = help;
    }
     
    function setupHelp() {
      var helpText = [
          {'id': 'email', 'help': 'Your e-mail address'},
          {'id': 'name', 'help': 'Your full name'},
          {'id': 'age', 'help': 'Your age (you must be over 16)'}
        ];
     
      for (var i = 0; i < helpText.length; i++) {
        var item = helpText[i];
        document.getElementById(item.id).onfocus = function() {
          showHelp(item.help);
        }
      }
    }
     
    setupHelp();
    

    reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

  • Closures, performance considerations and use of prototypes https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
    It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.
     
    For instance, when creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called, the methods would get reassigned (that is, for every object creation).
     
    Consider the following impractical but demonstrative case:
     
    function MyObject(name, message) {
      this.name = name.toString();
      this.message = message.toString();
      this.getName = function() {
        return this.name;
      };
     
      this.getMessage = function() {
        return this.message;
      };
    }
    The previous code does not take advantage of the benefits of closures and thus could instead be formulated:
     
    function MyObject(name, message) {
      this.name = name.toString();
      this.message = message.toString();
    }
    MyObject.prototype = {
      getName: function() {
        return this.name;
      },
      getMessage: function() {
        return this.message;
      }
    };
    However, redefining the prototype is not recommended, so the following example is even better because it appends to the existing prototype:
     
    function MyObject(name, message) {
      this.name = name.toString();
      this.message = message.toString();
    }
    MyObject.prototype.getName = function() {
      return this.name;
    };
    MyObject.prototype.getMessage = function() {
      return this.message;
    };
     
     
     
    Associative property of JavaScript objects to add an extend function to the Object.prototype:
    Object.prototype.extend = function(obj) {
           for (var i in obj) {
              if (obj.hasOwnProperty(i)) {
                 this[i] = obj[i];
              }
           }
        };
    You can then use this function as shown below.
     
        var o = { member: "some member" };
        var x = { extension: "some extension" };
     
        o.extend(x);
     
    
  • Prototype https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model
  • Module pattern Anonymous closures
    (function () {
            // ... all vars and functions are in this scope only
            // still maintains access to all globals
    }());
    

    Importing global variables

    (function ($, YAHOO) {
            // now have access to globals jQuery (as $) and YAHOO in this code
    }(jQuery, YAHOO));
    

    Exporting global variables

    var MODULE = (function () {
            var my = {},
                    privateVariable = 1;
     
            function privateMethod() {
                    // ...
            }
     
            my.moduleProperty = 1;
            my.moduleMethod = function () {
                    // ...
            };
     
            return my;
    }());
     
     
    

    reference: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

  • Temporary extends
    var friend = {
        car: false,
        lendCar: function ( canLend ){
          this.car = canLend;
    }
     
    };
     
    var me = {
        car: false,
        gotCar: function(){
          return this.car === true;
      }
    };
     
    console.log(me.gotCar()); // false
    friend.lendCar.call(me, true); //function extended to me temporarily
    console.log(me.gotCar()); // true
    friend.lendCar.apply(me, [false]);
    console.log(me.gotCar()); // false
    
  • Javascript events JavaScript HTML events: onClick, etc.
    server-side: eventemitter
    html 5: custom events
  • AMD and CommonJS
    AMD: Async module definition - RequireJS
    
    - browser-side scripting: parallel loading of JS files, performance
    
    
    CommonJS: sync module definitions - CommonJS
    - node.js, server-side programming
    - Browserify can bundle all main+dependent JS files into one file - that can be used in browser.

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