当我使用原型在Javascript中实现继承时,我遇到了一个奇怪的错误。我想知道是否有人可以解释这一点。在以下代码中, 我试图从父类派生一个子类:
parent_class=function(byref)
{
if( !parent_class.prototype._vtbl )
{
parent_class.prototype.parent_func= function(o) { return alert("parent_func"); }
parent_class.prototype._vtbl = true;
}
}
child=function(byref)
{
parent_class.call(this,byref);
if( !child.prototype._vtbl )
{
child.prototype = new parent_class;
child.prototype.child_func = parent_class.prototype.parent_func;
child.prototype._vtbl = true;
}
}
function dotest()
{
var pub = new child;
alert( pub.child_func );
var pub2 = new child;
alert( pub2.child_func );
}
dotest();
在浏览器(Firefox或IE)中运行测试时,会收到两个警报。第一个说pub.child_func是未定义的,第二个说pub.child_func是一个有效的函数,是parent_class.parent_func。为什么你会看到这种行为。这是一个错误吗?
答案 0 :(得分:1)
这种构造的javascript中的执行顺序:
AWS.config = new AWS.Config();
AWS.config.accessKeyId = "accessKey";
AWS.config.secretAccessKey = "SecretAccessKey";
就是这样:
function SomeClass () { body(); }
var x = new SomeClass();
的新对象(此处选择了对象的原型,在执行构造函数的代码之前)SomeClass.prototype
被执行在您的示例中,您可以使用.__proto__
,尽管您确实不应该这样做:
body();
你真正应该做的是:
child = function (byref) {
parent_class.call(this, byref);
if (!child.prototype._vtbl) {
child.prototype = new parent_class;
child.prototype.child_func = parent_class.prototype.parent_func;
child.prototype._vtbl = true;
}
this.__proto__ = child.prototype;
}
答案 1 :(得分:0)
执行JavaScript继承的更简单方法可能是工厂模式:
function Animal(name) {
return {
run: function() {
alert(name + " is running!")
}
}
}
var animal = Animal("fox");
animal.run();
function Rabbit(name) {
var rabbit = Animal(name);
rabbit.bounce = function() {
this.run();
console.log(name + " bounces");
}
return rabbit;
}
var rabbit = Rabbit("rabbit");
rabbit.bounce();
来源:http://javascript.info/tutorial/factory-constructor-pattern
答案 2 :(得分:0)
简短回答:不,这不是浏览器错误,这是预期的行为。
详细答案:
当使用new
调用构造函数时,对prototype
的引用将被复制到对象的__proto__
中。稍后,此属性用于此对象的原型查找。
从构造函数调用执行期间修改prototype
构造函数时,从javascript开发人员的角度来看,您的代码非常奇怪。但是,它的工作原理。因为,在var parent = new parent_class();
之后,以下内容为parent.__proto__ === parent_class.prototype
。这是相同的参考。因此,通过原型查找自动将parent_class.prototype
对象添加到parent
对象中。
不幸的是我还不能发表评论,所以我必须从我的答案中提及,@RyszardFiński它不是一个正确的陈述,prototype
在构造函数被调用之前定义,之后无法更改。它是相同的对象,除非您更改引用,否则将立即反映所有实例化对象的更改
然而,在child
代码中,当child.prototype
被分配给新对象时,OP废墟引用。
child.prototype = new parent_class;
child.prototype
开始指向parent_class
的新实例(#1)。实例引用如下所示
pub.__proto__ === child.prototype
pub2.__proto__ === parentInstance1
child.prototype === parentInstance2
如果删除分配了child.prototype
的代码行,一切都会按预期开始工作
pub.__proto__ === child.prototype
pub2.__proto__ === child.prototype
child.prototype === child.prototype
child.prototype has properties _vtbl and child_func