Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/459.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript中的继承_Javascript_Internet Explorer_Firefox - Fatal编程技术网

Javascript中的继承

Javascript中的继承,javascript,internet-explorer,firefox,Javascript,Internet Explorer,Firefox,当我使用原型在Javascript中实现继承时,我遇到了一个奇怪的错误。我想知道是否有人能解释这一点。在下面的代码中, 我正在尝试从父类派生子类: parent_class=function(byref) { if( !parent_class.prototype._vtbl ) { parent_class.prototype.p

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

这种结构的javascript执行顺序:

function SomeClass () { body(); }
var x = new SomeClass();
这是:

  • SomeClass.prototype
    继承的新对象已创建(在执行构造函数的代码之前,在此选择对象的原型)
  • body()被执行
  • 创建的对象已指定给x
  • 在您的示例中,您可以使用,尽管您确实不应该:

    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;
    }
    
    你真正应该做的是:

    child = function (byref) {
        parent_class.call(this, byref);
    }
    child.prototype = Object.create(parent_class.prototype);
    child.prototype.child_func = parent_class.prototype.parent_func;
    child.prototype._vtbl = true;
    

    执行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();
    

    来源:

    简短回答:不,这不是浏览器错误,这是预期行为

    详细答案: 当使用
    new
    调用构造函数时,对其
    原型的引用将复制到对象的
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    中。稍后,此属性用于此对象的原型查找
    从javascript开发人员的角度来看,当您在构造函数调用执行期间修改构造函数的
    prototype
    时,您的代码非常奇怪。然而,它是有效的。因为,在
    var parent=new parent_class()之后以下是正确的
    父级。uuu proto_uuu===parent\u class.prototype
    。这是相同的参考。因此,将属性添加到
    parent_类中。prototype
    会通过原型查找在
    parent
    对象中自动重新影响。 不幸的是,我还不能发表评论,所以我必须从我的回答中引用,@RyszardFiński说,
    prototype
    是在构造函数调用之前定义的,之后不能更改,这不是一个正确的说法。它是同一个对象,除非您更改引用,否则所有实例化对象的更改将立即反映出来

    但是,在
    child
    中,当
    child.prototype
    分配给新对象时,OP中的code会破坏引用

    child.prototype=新的父类

    child.prototype
    开始指向父类(#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
    

    这是代码中的一个bug。不要在构造函数中初始化原型!如果您想使用工厂模式,以便在不使用
    new
    (如
    rabbit=Animal(name);
    )的情况下调用函数,那么您不能使用
    。您是对的,严重的复制和粘贴错误…已修复,谢谢您指出。您的建议有效。我现在明白为什么了。但这是否意味着这是一个可接受的替代方案?Bergi指出的讨论似乎不是决定性的。真正的目标是找到一种方法,使函数表不是每次都重新创建,而是只重新创建一次。实现这一点的最佳方法是什么?虽然我的帖子是对你最初的确切问题(它的表述方式)的确切回答,但我认为这不是一个很好的继承方法。对于使用私有变量的函数,无法实现单个函数表,但是可以将它们复制到新对象的原型中。因为JS中的继承是原型而不是经典。如果你真的想在这方面有点学术性,我建议你仔细阅读