yodabar
yodabar

Reputation: 4799

Variable access from JavaScript inherited methods

I am studying the accessibility to variables from methods inherited from a parent to a child object.

The inheritance is performed associating an instance of the parent to the prototype of the child's constructor:

Function.prototype.extend = function(child) {
    var prototype = new this;

    child.prototype = prototype;
    return child;
};

So I define a parent class:

var Parent = function() {
    var self = this;

    this.init = function() {
        self.name = 'Abram';
    };
    this.getName = function() {
        alert('self.name = ' + self.name);
    };
    this.init();
};

and a child class:

var Baby = Parent.extend(function(name) {
    var self = this;

    this.init = function() {
        self.name = name;
    };
    this.init();
});

// instantiate a child object:
var baby = new Baby('Jimmy');

// call the inherited method:
baby.getName(); // undefined!

The method getName is correctly inherited, but it has no access to the self.name member.
How come, if it is available in the scope of the child class instance?

Checking the body of the method with alert(baby.getName) I get:

function () {
    alert("self.name = " + self.name);
}

which is exactly what I expected.
But why it does not resolve the self variable locally?

Upvotes: 4

Views: 2934

Answers (1)

Pointy
Pointy

Reputation: 414086

The variable "self" in the parent "getName()" function refers to the parent instance. The "init" function in the child sets the name on that object, not the prototype object.

Thus:

  1. var baby = new Baby("Jimmy"); results in an object with a "name" property set to the string "Jimmy"
  2. baby.getName(); calls the function on the prototype object, since there's no "getName" property on the "baby" object. Inside that function, a reference is made to the variable "self", which refers to that prototype object — not to the object "baby". There's no "name" property set on the prototype object.

See what happens if you change the .getName() function in the prototype to use this.name instead of self.name.

Upvotes: 3

Related Questions