简体   繁体   English

对原型继承Java语言感到困惑

[英]Confused on Prototype inheritance Javascript

I found this picture here 我在这里找到这张照片 在此处输入图片说明

In this case, foo is a constructor function and B and C are objects. 在这种情况下,foo是构造函数,而B和C是对象。 I am very confused, first off when you create an object does it always come with the properties and proto ? 我很困惑,首先创建对象时,它是否总是随属性和proto一起提供 Is that the default? 这是默认值吗? Also in terms of the constructor function for foo. 另外就foo的构造函数而言。 Am I correct to say that every proto of a function defaults to Function.prototype, which uses Object.prototype to create an object? 我是否正确地说一个函数的每个原型都默认为Function.prototype,该函数使用Object.prototype创建对象? The part that is confusing for me is Foo.prototype, when was this prototype created? 对我来说令人困惑的部分是Foo.prototype,这个原型是何时创建的? Does a constructor function always default to the creation of a prototype which a constructor reference set back to itself and a proto set to object? 构造函数是否始终默认为创建原型,而原型将构造函数引用重新设置为自身,并将原型设置为对象?

The properties are assigned in the construction function. 在构造函数中分配属性。 Any function can be used with new ,thus becoming the "construction function". 任何功能都可以与new一起使用,从而成为“构造功能”。

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

If there are no properties assigned in that function (using this.propertyName ), then the constructed instance will not have properties. 如果在该函数中未分配任何属性(使用this.propertyName ),则构造的实例将没有属性。 If it does, then it will. 如果是这样,那么它将。

// 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";
};

If the prototype of the construction function has properties or methods (basically just glorified properties) attached to its prototype, then each instance will have those. 如果构造函数的原型具有附加到其原型的属性或方法(基本上只是美化的属性),则每个实例都将具有这些属性或方法。

// No prototype
var f = function(){}; 

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

The prototypes and properties must be manually created, and may or may not exist. 原型和属性必须手动创建,并且可能存在或可能不存在。 By default, since using new requires a function, there will always be a constructor function. 默认情况下,由于使用new 需要一个函数,因此总会有一个构造函数。 The process of instantiation using new will also always assign the prototype of the constructor to an object containing the constructing function as a property named constructor as well as all of the properties/methods of the construction function's prototype. 使用new进行实例化的过程还将始终将构造函数的原型分配给包含构造函数的对象,该对象名为constructor ,以及构造函数原型的所有属性/方法。

In this case, foo is a constructor function and B and C are objects. 在这种情况下,foo是构造函数,而B和C是对象。

Functions are also objects. 功能也是对象。 Everything are objects. 一切都是对象。 unlike classical inheritance where what defined objects are separate entities. 与经典继承不同,经典继承中定义的对象是单独的实体。 Here an object that is an instance of Function is the constructor that will create an instance of its kind that inherits whatever object is on the constructors prototype attribute. 在这里,作为Function实例的对象是构造函数,它将创建此类实例,该实例继承构造函数原型属性上的任何对象。

I am very confused, first off when you create an object does it always come with the properties and proto? 我很困惑,首先创建对象时,它是否总是随属性和原型一起提供的? Is that the default? 这是默认值吗?

Only way to get the objects own property y is if the constructor function sets this.y . 获取对象自己的属性y唯一方法是构造函数设置了this.y If a property is not found on the object the system will continue to look at the object that was on the constructors prototype field. 如果在对象上找不到属性,则系统将继续查看构造函数原型字段上的对象。 Some implementations has this as __proto__ but that is not a requirement. 一些实现将此作为__proto__但这不是__proto__ It is implementation specific how it is stored on the instance. 它是特定于实现的,如何将其存储在实例上。

Also in terms of the constructor function for foo. 另外就foo的构造函数而言。 Am I correct to say that every proto of a function defaults to Function.prototype, which uses Object.prototype to create an object? 我是否正确地说一个函数的每个原型都默认为Function.prototype,该函数使用Object.prototype创建对象?

function() {...} makes an instance of the constructor Function . function() {...}构成构造Function的实例。 All objects except Object itself inherits Object either indirectly or directly, including Function . Object本身以外的所有对象都间接或直接继承Object ,包括Function Basically you can make a function like this: 基本上,您可以创建如下函数:

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

f is an instance of Function , as you can see. 如您所见, fFunction的实例。 This is almost the same as: 这几乎与以下内容相同:

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

Now the first allows for text to be interpreted as code so its less efficient, but I imagine that in the early days these two would be identical in terms of interpretation. 现在,第一个方法允许将文本解释为代码,因此效率较低,但是我想在早期,这两个在解释方面是相同的。 Modern engines prefer the last one since it is more predictable while the first can be seen as a specialized eval . 现代引擎更喜欢最后一个引擎,因为它更容易预测,而第一个引擎可以看作是专门的eval

The part that is confusing for me is Foo.prototype, when was this prototype created? 对我来说令人困惑的部分是Foo.prototype,这个原型是何时创建的? Does a constructor function always default to the creation of a prototype which a constructor reference set back to itself and a proto set to object? 构造函数是否始终默认为创建原型,而原型将构造函数引用重新设置为自身,并将原型设置为对象?

Yes. 是。 When the function Foo is created, JS creates by default protoype as new Object() , then it sets constructor to itself. 创建函数Foo ,JS默认情况下将原型创建为new Object() ,然后将constructor设置为其自身。 The rest needs to be done in the code itself so we know there is something like this after the actual function code to do the rest of the class: 其余的工作需要在代码本身中完成,因此我们知道在实际的函数代码之后还有类似的事情可以完成该类的其余工作:

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

No wonder there is confusion. 难怪会有混乱。 The picture is misleading to the point of being incorrect! 图片误导到不正确的地步!

Objects created by calling a constructor function with the new keyword have their inheritance chain set to start with the prototype property of the constructor (correct in the picture). 通过使用new关键字调用构造函数创建的对象的继承链设置为以构造函数的prototype属性开头(图中正确)。

The prototype property is created every time a function is declared using the function keyword to cover the case of the function being use as a constructor later - so you don't need to specify if a function is a constructor or not. 每次使用function关键字声明函数时都会创建prototype属性, 以覆盖该函数以后用作构造函数的情况 -因此,您无需指定函数是否为构造函数。 For completeness, functions generated by the class keyword also have a prototype property.) 为了完整起见,由class关键字生成的函数还具有prototype属性。)

The function's prototype property's constructor property is set to the function when the prototype property is created (meaning when the function is declared). 函数的原型属性的constructor函数属性在创建原型属性时(即声明函数时)设置为该函数。 Again the picture is correct: the value of Foo.prototype.constructor is a reference to Foo . 同样,图片是正确的: Foo.prototype.constructor的值是对Foo的引用。

What is wrong in the picture is objects a and b somehow joining together in a reverse fork and their properties becoming available to instances of Foo . 图片中的问题是对象ab以某种方式以反向叉的形式连接在一起,并且它们的属性可用于Foo实例。

constructor is always an inherited property. constructor始终是继承的属性。 If you replace the original prototype property of a function object with another object, you replace the constructor property inherited by objects constructed with the function. 如果将功能对象的原始prototype属性替换为另一个对象,则将由该函数构造的对象继承的constructor属性替换。 Although you can reset the constructor property of a functions prototype property, it's reasonably unusual and not a part of the story the picture is presenting. 尽管您可以重置函数prototype属性的constructor函数属性,但这是相当不寻常的,并且不是图片所呈现故事的一部分。

If you do modify the inheritance chain by changing a function's prototype property value, the inheritance chain is still always a single threaded chain back to Object.prototype and then null . 如果确实通过更改函数的prototype属性值来修改继承链,则继承链始终始终是返回给Object.prototype ,然后为null单线程链。 The inheritance chain never forks as shown in the picture. 继承链永远不会分叉,如图所示。 If you modified Foo.prototype in the picture to make it a or b , the constructor property of Foo instances would not be Foo . 如果您修改Foo.prototype的图像,使其ab ,在constructor的性质Foo情况下不会是Foo

The picture requires a lot of explanation to be useful. 图片需要很多说明才能有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM