[英]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. 如您所见, f
是Function
的实例。 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
. 图片中的问题是对象a
和b
以某种方式以反向叉的形式连接在一起,并且它们的属性可用于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
的图像,使其a
或b
,在constructor
的性质Foo
情况下不会是Foo
。
The picture requires a lot of explanation to be useful. 图片需要很多说明才能有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.