迷惑Prototype继承Javascript

时间:2018-06-14 22:23:13

标签: javascript inheritance prototype

我在这里找到了这张图片enter image description here

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

3 个答案:

答案 0 :(得分:0)

属性在构造函数中指定。任何函数都可以与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进行实例化的过程也总是将构造函数的原型分配给包含构造函数的对象,作为名为constructor的属性以及构造函数原型的所有属性/方法。

答案 1 :(得分:0)

  

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

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

  

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

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

  

另外就foo的构造函数而言。我说对了   一个函数的每个proto默认为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(...) {...};

答案 2 :(得分:0)

难怪有混乱。这张照片误导了不正确的地方!

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

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

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

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

constructor始终是继承的属性。如果将函数对象的原始prototype属性替换为另一个对象,则替换由该函数构造的对象继承的constructor属性。虽然您可以重置函数constructor属性的prototype属性,但这是相当不寻常的,而不是图片所呈现的故事的一部分。

如果您通过更改函数的prototype属性值来修改继承链,则继承链仍然始终是返回Object.prototype然后null的单线程链。继承链永远不会如图所示。如果您修改了图片中的Foo.prototype以使其ab,那么constructor个实例的Foo属性将不会是Foo。< / p>

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