4

Why does following snippet work in Angular JS?

var app = angular.module('store',[]); 



(function(){
    app.controller('StoreController',function(){
        this.blabla = student;
    });
})();

var student = 
{
    name:"Abc Def",
    rollNumber:12,
    isBrilliant: true,
    isMale:false,
    isFemale: false,
    istest:true
};

Even though student comes after the function where it's being used and student is not hoisted still why does the above function work?

But in contrast to the above example, this one:

(function(){
        console.log("Name is :"+student);
    })();

    var student = {
        name:"xyz"
    };

Shows student as undefined means it wasn't hoisted.

user4904589
  • 547
  • 2
  • 5
  • 15
  • `this.blabla = student;` isn't executed until Angular instantiates the controller, which would happen after you defined student. – Anid Monsur Sep 17 '15 at 04:45
  • Its is because angular uses a digest cycle and keep on updating the value of $scope and others .... So it repeatedly checks and update $scope with newer values – binariedMe Sep 17 '15 at 04:45
  • 1
    Checkout [this](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) article for the 2nd point.It's **IIFE** – road2victory Sep 17 '15 at 05:50

2 Answers2

8

.controller registers a controller function but doesn't execute it right away - it enqueues it for a later phase. Then, student variable is assigned an object.

That controller function, however, is a closure over student variable - in other words, it has access to it at run-time. Read more about closures. And so, when it does finally execute, student variable is defined.

In contrast, the second example's console.log, whether it is enclosed in immediately-invoked function expression or not, executes before student variable is assigned, and so it is undefined.

New Dev
  • 48,427
  • 12
  • 87
  • 129
5

There is a subtle difference between the first example and the second example. In the first example, there are two function blocks, in the second, there is only one.

Both examples are invoked immediately, but where the second function tries immediately to access the outer variable, which hasn't been defined yet, the first merely executes a function to register the controller (and thus, does not execute the contents of the controller function).

By the time the angular framework invokes the controller's constructor function, the outer variable has been defined, and is part of the closure environment.

Claies
  • 22,124
  • 4
  • 53
  • 77