简单的问题。
function p()
{
function A()
{
this.random = "random";
}
A.prototype.newfunc = function(){ alert("5");}
function B()
{
}
B.prototype = new A();
var bObj = new B();
}
Q1:当我设置B的原型时,我不知道B的原型属性将在何时/如果A的原型更新时更新。我的意思是,对我来说它只是继承/复制所有这些属性。它不像是:
B.prototype = A.prototype
其中B和A是同一个。
Q2:在A被返回并初始化为B的原型对象之后,JS如何知道不包含该原型属性?我的意思是,我们从来没有出现过这种情况,因为JS解释器只知道切断A原型的属性:
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
答案 0 :(得分:2)
Q1:你自己说过 - 原型用于继承。因此B继承了A的所有属性。当您添加或更改A的成员时,B也会更改。正如你所说,它们不一样,但A是B的超类,如果超类中的任何内容发生变化,子类也会发生变化。但是,您可以将成员添加到B.prototype并在不更改A的情况下更改其行为。
试试这个:
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:再次,继承与组合不同。当您指定B.prototype时,您不只是将A类型的对象放在占位符中,而是更改B类型的所有对象的“蓝图”。因此,当您访问所述蓝图时,您不会获得对象类型A的蓝图,但是包含对类型A的蓝图的引用的类型B的蓝图。该蓝图将不具有类型原型的成员,因为原型不是任何类的“常规”成员。将其添加到上面的代码中:
function iterateMembers ( obj ) {
var str = "";
for (var member in obj) {
str += member + ", "
}
alert (str);
}
iterateMembers (aObj);
iterateMembers (A.prototype);
注意aObj和A.prototype都不包含成员“prototype”。现在打电话
iterateMembers (A);
alert (typeof(A));
现在应该很明显,prototype是type函数的一个成员,并且由于函数不是由A或B继承的(事实上,它不能被继承),它们都不包含名字的成员“原型”。
答案 1 :(得分:1)
Q1:当我设置B的原型时,我不知道B的原型属性将在何时/如果A的原型更新时更新。我的意思是,对我而言,它只是继承/复制所有这些属性。
函数对象具有prototype
字段:
function A(name) { this.name = name }
print(A.prototype) // [object Object]
使用new A
创建对象时,生成的对象包含constructor
字段,该字段是对构造函数的引用:
var a = new A('Eric')
print(a.constructor == A) // True
print(a.constructor.prototype == A.prototype) // True
如果您尝试索引a
并且字段未定义,JavaScript将尝试通过a
的原型(例如a.constructor.prototype
)解析它。我们可以使用它来向所有A
实例添加内容:
A.prototype.greet = function() { print('Hi, ' + this.name + '!') }
a.greet() // Hi, Eric!
此字段解析以递归方式工作。
function B(name) { this.name = name.toUpperCase() }
B.prototype = new A
b = new B("Eric")
b.greet() // Hi, ERIC!
最后一行中发生的事情是JavaScript在b
中找不到“问候”字段,因此它会尝试b
的原型。它也没有找到,所以它尝试* b
的原型的原型,依此类推,直到它用完了原型。
口译员知道要切断A原型的属性: B.prototype.prototype
没有什么被砍掉,你只是在看错了。你想要:
B.prototype.constructor.prototype