0

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?

Gonki
  • 567
  • 1
  • 8
  • 17
  • 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. Hence they the second box definition overrides the first definition. – Aravind Nov 16 '14 at 15:22
  • Is __construct more than a function name in the code? – Gonki Nov 16 '14 at 15:22
  • 2
    That code doesn't make any sense... – plalx Nov 16 '14 at 15:28
  • The following answer may be helpful to you: http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Nov 16 '14 at 15:44

1 Answers1

2

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();
Aravind
  • 3,169
  • 3
  • 23
  • 37
  • Realized same thing. I will name them box_test1, box_test2. I think it may be a good thing to try: having private object functions in global(window) under different vars (box_test1, 2 in this case). – Gonki Nov 16 '14 at 15:33
  • I actually meant to completely remove those local `__construct` functions, but +1 nonetheless. – Bergi Nov 16 '14 at 15:44
  • Does this code work? I get "Cannot read property 'test_' of undefined " error on "return this.box.test_()" line – Gonki Nov 16 '14 at 16:25
  • @Gonki: Take some time and understand how it works. It will be well worth the time spent. – Aravind Nov 16 '14 at 17:18
  • I've been reading up on object construction techniques. It may be that the configuration described here is a rugged one. All object data and functions are kept private and prototype provides only marshaling calls from public to private. I was missing the call() function (although call() did occur to me as a possible solution but I didn't see how to use it correctly with "this"). – Gonki Nov 16 '14 at 17:25