Javascript中的继承

时间:2015-06-28 11:18:42

标签: javascript internet-explorer firefox

当我使用原型在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。为什么你会看到这种行为。这是一个错误吗?

3 个答案:

答案 0 :(得分:1)

这种构造的javascript中的执行顺序:

AWS.config = new AWS.Config();
AWS.config.accessKeyId = "accessKey";
AWS.config.secretAccessKey = "SecretAccessKey";

就是这样:

  1. 创建了继承自function SomeClass () { body(); } var x = new SomeClass(); 的新对象(此处选择了对象的原型,在执行构造函数的代码之前)
  2. SomeClass.prototype被执行
  3. 创建的对象分配给x
  4. 在您的示例中,您可以使用.__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