2

Simple questions.

    function p()
    {
        function A()
        {
            this.random = "random";
        }
        A.prototype.newfunc = function(){ alert("5");}

        function B()
        {

        }

        B.prototype = new A();

        var bObj = new B();
    }

Q1: When I set B's prototype, I don't get how B's prototype property will update when/if A's prototype is updated. I mean, to me it just inherits/copies all those properties. It's not like it's:

B.prototype = A.prototype

where B and A are one in the same.

Q2: After A is being returned and intialized to the prototype object of B, how does JS know not to include that prototype property? What I mean is, we never have this type of situation occuring as the JS interpreter knows just to chop off the property of A's prototype:

B.prototype = new A(); //any A object has an associated prototype object
    B.prototype.prototype;//after initialization we no longer have the separate prototype property of A

2 Answers 2

2

Q1: You said it yourself - prototype is used for inheritance. Therefore B inherits all properties of A. When you add or change members of A, B will also change. They are not the same, as you correctly say, but A is B's superclass, and if anything in the superclass changes, so will the subclass. You can, though, add members to B.prototype and change its behavior without changing A.

try this:

    function A()
    {
    }

    A.prototype.alertname = function () 
    {
        alert (this.name);
    };

    function B()
    {
    }

    B.prototype = new A();

    var bObj = new B();
    var aObj = new A();

    A.prototype.name = "A"; 
    aObj.alertname(); // output is "A";
    bObj.alertname(); // output is "A";

    B.prototype.name = "B";
    aObj.alertname(); // output is "A";
    bObj.alertname(); // output is "B";

Q2: Again, inheritance is different from composition. When you assign B.prototype, you don't just put an object of type A in a place holder, but change the "blueprint" for all objects of type B. So when you access said blueprint, you don't get an object of type A, but a blueprint of type B that contains a reference to the blueprint of type A. This blueprint will not have a member of type prototype, since prototype is not a "regular" member of either class. Add this to the code above:

function iterateMembers ( obj ) {
    var str = "";
    for (var member in obj) {
        str += member + ", "
    }
    alert (str);
}

iterateMembers (aObj);
iterateMembers (A.prototype); 

Notice how neither aObj nor A.prototype contain a member "prototype". Now call

iterateMembers (A);
alert (typeof(A));

It should be obvious now that prototype is a member of the type function, and since function is not inherited by either A nor B (in fact, it can't be inherited), neither of those contain a member with the name "prototype".

Sign up to request clarification or add additional context in comments.

2 Comments

Ok, thanks. As an aside, in C# when you inherit from your base class, there is still an implicit link from the variables you inherit to the classes they inherited from. Thus, if sub inherits super, although sub may have access to all of super's publics, they still know that they are in some way linked to the super class. Is prototype inheritance in JS the same thing or are all of the super class's prototype and class members just "duplicated" on over?
No, you just want to call A.prototype.constructor.prototype.
1

Q1: When I set B's prototype, I don't get how B's prototype property will update when/if A's prototype is updated. I mean, to me it just inherits/copies all those properties.

Function objects have a prototype field:

function A(name) { this.name = name }

print(A.prototype) // [object Object]

When you create an object using new A, the resulting object contains a constructor field which is a reference to the constructor function:

var a = new A('Eric')

print(a.constructor == A) // True
print(a.constructor.prototype == A.prototype) // True

If you attempt to index a and the field is undefined, JavaScript will attempt to resolve it via a's prototype (e.g.a.constructor.prototype). We can use this to add things to all A instances:

A.prototype.greet = function() { print('Hi, ' + this.name + '!') }

a.greet() // Hi, Eric!

This field resolution works recursively.

function B(name) { this.name = name.toUpperCase() }
B.prototype = new A
b = new B("Eric")
b.greet() // Hi, ERIC!

What's happening in this last line is that JavaScript finds no 'greet' field in b, so it tries b's prototype. It's not found there either, so it tries *b's prototype's prototype, and so on up the chain, until it runs out of prototypes.

Interpreter knows just to chop off the property of A's prototype: B.prototype.prototype

Nothing is chopped off, you're just looking at the wrong thing. You want:

B.prototype.constructor.prototype

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.