【问题标题】:Confused on Prototype inheritance Javascript对原型继承 Javascript 感到困惑
【发布时间】:2018-06-14 22:23:13
【问题描述】:

我在这里找到了这张照片

在这种情况下,foo 是构造函数,B 和 C 是对象。我很困惑,首先当你创建一个对象时,它总是带有属性和proto吗?这是默认的吗?同样就 foo 的构造函数而言。我是否正确地说函数的每个 proto 都默认为 Function.prototype,它使用 Object.prototype 创建对象?令我困惑的部分是 Foo.prototype,这个原型是什么时候创建的?构造函数是否总是默认创建一个原型,构造函数引用设置回自身,proto 设置为对象?

【问题讨论】:

标签: javascript inheritance prototype


【解决方案1】:

难怪会有混乱。图片误导到了不正确的地步!

通过使用 new 关键字调用构造函数创建的对象的继承链设置为从构造函数的 prototype 属性开始(在图片中正确)。

每次使用 function 关键字声明函数时都会创建 prototype 属性以涵盖稍后将函数用作构造函数的情况 - 所以你不需要指定函数是否为构造函数。为了完整起见,class 关键字生成的函数也有一个prototype 属性。)

函数的原型属性的constructor 属性在原型属性创建时(即函数声明时)设置为函数。图片再次正确:Foo.prototype.constructor 的值是对Foo 的引用。

图片中的问题是对象ab 在反向分叉中以某种方式连接在一起,并且它们的属性可用于Foo 的实例。

constructor 始终是继承属性。如果将函数对象的原始prototype 属性替换为另一个对象,则会替换使用该函数构造的对象继承的constructor 属性。尽管您可以重置函数 prototype 属性的 constructor 属性,但它相当不寻常,并且不属于图片所呈现的故事的一部分。

如果您确实通过更改函数的prototype 属性值来修改继承链,则继承链始终是返回Object.prototypenull 的单线程链。如图所示,继承链永远不会分叉。如果将图片中的Foo.prototype修改为ab,则Foo实例的constructor属性不会是Foo

图片需要大量解释才能有用。

【讨论】:

    【解决方案2】:

    属性在构造函数中分配。任何函数都可以与new一起使用,从而成为“构造函数”。

    var f = function(){};
    var fInstance = new f();
    console.log(fInstance.constructor); // *f*
    

    如果该函数中没有分配属性(使用this.propertyName),则构造的实例将没有属性。如果是,那么它会的。

    // No properties
    var f = function(){};
    
    // Two constructor properties, and one default property
    var f = function(prop1, prop2){
        this.name = prop1;
        this.description = prop2;
        this.something = "default";
    };
    

    如果构造函数的原型具有附加到其原型的属性或方法(基本上只是美化的属性),那么每个实例都会有这些。

    // No prototype
    var f = function(){}; 
    
    // Prototype with one method
    var f = function(){};
    f.prototype.test = function(){ console.log("hello"); };
    

    原型和属性必须手动创建,可能存在也可能不存在。默认情况下,由于使用new需要一个函数,所以总会有一个构造函数。使用new 进行实例化的过程也将始终将构造函数的原型分配给包含构造函数的对象,作为名为@9​​87654328@ 的属性以及构造函数原型的所有属性/方法。

    【讨论】:

      【解决方案3】:

      在这种情况下,foo 是构造函数,B 和 C 是对象。

      函数也是对象。一切都是对象。与经典继承不同,其中定义的对象是单独的实体。在这里,作为 Function 实例的对象是构造函数,它将创建一个同类实例,该实例继承构造函数原型属性上的任何对象。

      我很困惑,首先当你创建一个对象时 总是带有属性和原型?这是默认的吗?

      获取对象自己的属性y 的唯一方法是构造函数设置this.y。如果在对象上找不到属性,系统将继续查看在构造函数原型字段上的对象。一些实现将其命名为__proto__,但这不是必需的。它是如何存储在实例上的具体实现。

      同样是 foo 的构造函数。我说得对吗 函数的每个原型都默认为 Function.prototype,它 使用 Object.prototype 创建对象?

      function() {...} 创建构造函数Function 的实例。除了Object 本身之外的所有对象都间接或直接继承Object,包括Function。基本上你可以做一个这样的函数:

      var f = new Function('a', 'b', 'return a + b');
      

      fFunction 的一个实例,如您所见。这几乎是一样的:

      var f = function(a, b) { return a + b; };
      

      现在第一个允许将文本解释为代码,因此效率较低,但我想在早期,这两个在解释方面是相同的。现代引擎更喜欢最后一个,因为它更容易预测,而第一个可以被视为专门的eval

      令我困惑的部分是 Foo.prototype,这是什么时候 原型创建?构造函数是否总是默认为 创建一个原型,构造函数引用设置回 本身和一个原型设置为对象?

      是的。在创建函数Foo时,JS默认创建原型为new Object(),然后将constructor设置为自身。其余的需要在代码本身中完成,所以我们知道在实际的函数代码之后有这样的东西来完成类的其余部分:

      Foo.prototype.x = 10;
      Foo.prototype.calculate = function(...) {...};
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多