Robert
Robert

Reputation: 739

Accessing instance variable from parent function

I have an object that inherit from another one. In the child object, I initialize some instance variables. In the parent object, I have a method that call private functions that use these instance variables.

function objA() {
  this.funcA = function() {
    alert(this.var);
    funcB();
  };
  function funcB() {
    alert(this.var);
  };
}

objB.prototype = new objA();
objB.prototype.constructor = objB;
function objB() {
  this.var ="hello";
  this.funcA();
}

the first alert gives "hello", the second undefined...

I understant that 'this' in javascript is the identity of the object calling the function, not the instance itself... I assume that when calling funcB, i'm in some kind of parent context where the variable does not exists...

I'm a pure javascript newbie, and I can't figure out how to solve that. Of course, I could pass it as agument, but it's not very OOP, and in my project, there are a lot more variables to make availables...

Thanks

Upvotes: 3

Views: 6990

Answers (3)

Diode
Diode

Reputation: 25155

When the function is invoked like funcB(), inside the function 'this' will be Window object. So usually a proxy variable is used for the instance of the object. Below you can see how to do it.

function objA() {

  var _this;

  this.super = function(){
    _this = this;  
  }

  this.funcA = function() {
    alert(this.var);
    funcB();
  };

  function funcB() {
    alert(_this.var);
  };
}

objB = function objB() {
  this.super();
  this.var ="hello";
  this.funcA();
}

objB.prototype = new objA();

var b = new objB();

Upvotes: 1

juandopazo
juandopazo

Reputation: 6329

Please don't abuse JavaScript's ability to define functions after they're used. It's really difficult to read code like that.

As you noticed, the problem is not in your inheritance chain, but in how you want to access this from the funcB function. Calling a function by doing foo() is not the same as calling obj.foo() or this.foo(). The value of this depends on how you call the function. When you do obj.foo() this will be obj. But if you call foo() the value of this will be the window object.

You can change the value of this inside a function by using Function.prototype.call and Function.prototype.apply so writing foo.call(obj) (now this will be obj). With that in mind your code will look like this:

function objA() {
  function funcB() {
    alert(this.var);
  }
  this.funcA = function() {
    alert(this.var);
    funcB.call(this); // <- notice .call()
  };
}

function objB() {
  this.var ="hello";
  this.funcA();
}
objB.prototype = new objA();
objB.prototype.constructor = objB;

Also, keep in mind that property names can't be reserved words (for example, "var") in older browsers.

Upvotes: 1

Dexygen
Dexygen

Reputation: 12561

Using prototype-based inheritance, you cannot access properties declared in the child, from the parent. Please see this developers guide from Mozilla:

https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_constructor_prototype and specifically where it says:

"Property look-up follows the prototype chain. All objects that share a common prototype chain share common properties."

The child shares the entire "common prototype chain" with the parent, but not vice versa. This does not mean there may not be other ways to accomplish what you are trying, however, prototype-based inheritance may not be that way.

Upvotes: 0

Related Questions