Gonki
Gonki

Reputation: 736

JavaScript variable isolation in constructors of separate objects

Looking at this code it should produce output "TEST1"+"TEST2" however I get "TEST2" twice:

function TEST1(){
   var __construct = function () { this.box = { test_ : function () {console.log('TEST1')} }}
   __construct()
}

TEST1.prototype = {t: function(){ return box.test_()} }


function TEST2(){
   var __construct = function () { this.box = { test_ : function () {console.log('TEST2')} }}
   __construct()
}

TEST2.prototype = {t: function(){ return box.test_()}}

var t1 = new TEST1()
var t2 = new TEST2()
t1.t()
t2.t()

If I rename "box" in second function I get correct output:

function TEST2(){
   var __construct = function () { this.box_ = { test_ : function () {console.log('TEST2')} }}
   __construct()
}

TEST2.prototype = {t: function(){ return box_.test_()}}

Why is there this what appears a variable isolation issue?

Upvotes: 0

Views: 78

Answers (1)

Aravind
Aravind

Reputation: 3179

It's because when you call __construct() the this value inside the __contruct is the global object, hence the box object got created on the global object. This is because Javascript has function scope, and nested functions do not get the this value of it's parent functions. Hence nested functions have an execution context of the global scope.

When you wrote:

var t1 = new TEST1();

The __construct() call created a box property on the global(window) object.

Then, when you wrote

var t2 = new TEST2()

The __construct() call saw that the global object already had a box property and over-wrote it.

Hence they the second box definition overrides the first definition.

@Bergi wanted a fix, though this is not an issue, and just correct behavior. :)

function TEST1(){
   var __construct = function () { this.box = { test_ : function () {console.log('TEST1')} }};
   __construct.call(this);
}

TEST1.prototype = {t: function(){ return this.box.test_()} };


function TEST2(){
   var __construct = function () { this.box = { test_ : function () {console.log('TEST2')} }};
   __construct.call(this);
}

TEST2.prototype = {t: function(){ return this.box.test_()}};

var t1 = new TEST1();
var t2 = new TEST2();
t1.t();
t2.t();

Upvotes: 2

Related Questions