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
精彩评论