开发者

Misunderstanding I have about javascript prototype inheritance

开发者 https://www.devze.com 2023-01-31 22:42 出处:网络
Simple questions. function p() { function A() { this.random = \"random\"; } A.prototype.newfunc = function(){ alert(\"5\");}

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
开发者_运维知识库


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".


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
0

精彩评论

暂无评论...
验证码 换一张
取 消