Tuesday 19 May 2015

Prototype chaining








Random JavaScript thoughts

function createFunction(){

var arr =  new Array();
for (var i = 0; i<=10; i++){
arr[i] =  function(){
return i;
}
}
return arr;
}

function createFunction(){

var arr =  new Array();
for (var i = 0; i<=10; i++)
{
arr[i] =  function(num)
{
return function()
{
return i;
}
}(i)
}
return arr;
}

var Parent =(function(){
   var count = 0;
   var that = this;
   var __construct = function Person(pName){
       that.name = pName;
   }
   __construct.prototype.sayHello =  function(msg){
      return that.name + " " + msg + "!!!";
   }
   __construct.getCount = function(){ return count++;}
  return __construct;
})()

var Child = (function(){
     var __childConstruct =  function Child(){}
      __childConstruct.prototype =  Parent.prototype;
      __childConstruct.prototype.childMethod =  function(){ return "child scope";}

     return __childConstruct;
 

})()



// x is a method assigned to the object using "this"
var A = function () {
    this.x = function () {
        alert('A');
    };
};
A.prototype.updateX = function(value) {
    this.x = function() {
        alert(value);
    }
};

var a1 = new A();
var a2 = new A();
a1.x();  // Displays 'A'
a2.x();  // Also displays 'A'
a1.updateX('Z');
a1.x();  // Displays 'Z'
a2.x();  // Still displays 'A'



**********************************************************************************

//anonymous functions are not bound to  the object in "this" context ...  meaning this object point to "window" in non-strict mode else "undefined" in strict mode

convention of placing an opening curly brace at the end of a line in JavaScript, rather than on the beginning of a new line. As shown here, this becomes more than just a stylistic preference in JavaScript.

var name = “The Window”;
var object = {
name : “My Object”,
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};

**********************************************************************************

QUESTION:

console.log(sum(2,3));   // Outputs 5
console.log(sum(2)(3));  // Outputs 5

function sum(x) {
  if (arguments.length == 2) {
    return arguments[0] + arguments[1];
  } else {
    return function(y) { return x + y; };
  }
}

function sum(x, y) {
  if (y !== undefined) {
    return x + y;
  } else {
    return function(y) { return x + y; };
  }
}


 // When a function is invoked, JavaScript does not require the number of arguments to match the number of arguments in the function definition. If the number of arguments passed exceeds the number of arguments in the function definition, the excess arguments will simply be ignored. On the other hand, if the number of arguments passed is less than the number of arguments in the function definition, the missing arguments will have a value of undefined when referenced within the function. So, in the above example, by simply checking if the 2nd argument is undefined, we can determine which way the function was invoked and proceed accordingly..

**********************************************************************************

QUESTION:


(function(){
  var a = b = 3;  // BEHIND THE SCENE :- b=3; var a= b;
})();

 
console.log("a defined? " + (typeof a !== 'undefined')); // non-strict mode false
console.log("b defined? " + (typeof b !== 'undefined')); // non-strict mode true


But how can b be defined outside of the scope of the enclosing function? Well, since the statement var a = b = 3; is shorthand for the statements b = 3; and var a = b;, b ends up being a global variable (since it is not preceded by the var keyword) and is therefore still in scope even outside of the enclosing function..

Note that, in strict mode (i.e., with use strict), the statement var a = b = 3; will generate a runtime error of ReferenceError: b is not defined, thereby avoiding any headfakes/bugs that might othewise result. (Yet another prime example of why you should use use strict as a matter of course in your code!)


**********************************************************************************

QUESTION:

BENEFITS OF 'use strict'


1) 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.

2) 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.

3) 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.

4) 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.

5) 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).

6) 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.


**********************************************************************************
CLOSURE:

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log("outer func:  this.foo = " + this.foo);
        console.log("outer func:  self.foo = " + self.foo);
        (function() {
            console.log("inner func:  this.foo = " + this.foo);
            console.log("inner func:  self.foo = " + self.foo);
        }());
    }
};

// Function defined , behind the scene ===> SCOPE CHAIN is created preloaded with GLOBAL VARIABLE OBJECT and saved to internal [[scope]] property.

 // Function called, behind the scene ===> EXECUTION CONTEXT is created and it's SCOPE CHAIN is built by copying the objects in function's [[scope]] property. After that LOCAL ACTIVATION OBJECT is created and pushed to front of context's scope chain.

 // SCOPE CHAIN :  is just pointer to variable objects


// GLOBAL VARIABLE OBJECT +  LOCAL ACTIVATION OBJECT

// In closures ==>  Function that is defined inside another function add the containing function ACTIVATION OBJECT into it's scope chain.


// Each function automatically gets two special variables as soon as function is called :  this +  arguments
 Inner function can not access these variables from outside function. It can be achieved by storing "this" in some variable which closure can access.

**********************************************************************************


(function() {
    console.log(1);
    setTimeout(function(){console.log(2)}, 1000);
    setTimeout(function(){console.log(3)}, 0);
    console.log(4);
})();


The browser has an event loop which checks the event queue and processes pending events. For example, if an event happens in the background (e.g., a script onload event) while the browser is busy (e.g., processing an onclick), the event gets appended to the queue. When the onclick handler is complete, the queue is checked and the event is then handled (e.g., the onload script is executed).

Similarly, setTimeout() also puts execution of its referenced function into the event queue if the browser is busy.

When a value of zero is passed as the second argument to setTimeout(), it attempts to execute the specified function “as soon as possible”. Specifically, execution of the function is placed on the event queue to occur on the next timer tick. Note, though, that this is not immediate; the function is not executed until the next tick. That’s why in the above example, the call to console.log(4) occurs before the call to console.log(3) (since the call to console.log(3) is invoked via setTimeout, so it is slightly delayed).

***********************************************************************************

var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        nextListItem();
    }
};

*************************************************************


var fibonacci = (function() {
  var memo = {};

  function f(n) {
    var value;
    if (n in memo) {
      value = memo[n];
    } else {
      if (n === 0 || n === 1)
        value = n;
      else
        value = f(n - 1) + f(n - 2);

      memo[n] = value;
    }

    return value;
  }

  return f;
})();



(function(x){
  return function(y){
  return x;
  }
})(1)(2)

"this" in javascript


















john papa style guide - angularJs