[英]Javascript __proto__ - clarification?
I have this function : 我有这个功能:
function Foo(){}
According to this picture : 根据这张图片:
>> Foo.prototype -> Foo {}
So if I write : 所以,如果我写:
Foo.prototype.constructor
Foo.prototype.constructor
Now - it references to the constructor function which created the Foo{}
object which is function Foo(){}
现在 - 它引用了构造函数 ,它创建了
Foo{}
对象,它是function Foo(){}
All ok. 一切都好。
So where is the question ? 那问题在哪里?
Foo.prototype
is an object instance --> Foo {}
Foo.prototype
是一个对象实例 - > Foo {}
And who is the constructor function of Foo{}
? 谁是
Foo{}
的构造函数?
it is the the function Foo(){}
它是
function Foo(){}
you can see it here in yellow : 你可以在这里看到黄色:
ok 好
But I was told here that : 但我在这里被告知:
So Foo.prototype.__proto__
should reference to the prototype
of function Foo(){}
and not to Object.prototype
! 所以
Foo.prototype.__proto__
应该引用function Foo(){}
的prototype
而不是Object.prototype
!
If I translate it : 如果我翻译它:
__proto__ is the ctor's prototype
_________________________________________________________________________________________
Foo.prototype.__proto__ is the function Foo(){} Foo.prototype
but this is wrong 但这是错误的
And i'm probably wrong because : 我可能错了,因为:
What am I missing ? 我错过了什么?
Note: First off, __proto__
is non-standard, use Object.getPrototypeOf
, though for shortness, and because I'm lazy, I did use prototype
quite a few times in this answer 注意:首先,
__proto__
是非标准的,使用Object.getPrototypeOf
,虽然为了Object.getPrototypeOf
,因为我很懒,我在这个答案中确实使用了prototype
很多次
Well, you're thrown of by your initial assumption, if I'm reading you correctly: 好吧,如果我正确地读你,你会被最初的假设所抛弃:
Foo.prototype -> Foo{}
The prototype of Foo
(which is a constructor) is, by definition an instance of Foo
. 根据定义,
Foo
的原型(它是一个构造函数)是Foo
一个实例。 But, because a constructor is a function, and a constructor returns an object of a particular instance, the prototype will be an augmented Object
either way. 但是,因为构造函数是一个函数,并且构造函数返回特定实例的对象,所以原型将是一个增强的
Object
。
I'm not a big fan of comparing prototypal ineritance to classical OOP, but think of it like this: 我不是将原型无效性与经典OOP进行比较的忠实粉丝,但是想到这样:
The Foo
prototype is sort of a mutable class definition (you can add methods and properties as you go along), the constructor creates an object that augments this prototype, and adds another layer of properties/methods on an instance level. Foo
原型是一种可变类定义(您可以随意添加方法和属性),构造函数创建一个对象来扩充此原型,并在实例级别添加另一层属性/方法。
Hence Foo.prototype instanceof Foo
is true. 因此
Foo.prototype instanceof Foo
是真的。 But, Foo
being an object: 但是,
Foo
是一个对象:
Object.getPrototypeOf(Foo.prototype) === Object.prototype
is true. 是真的。 Just as
就像
Object.getPrototypeOf(Array.prototype) === Object.prototype.
Translate this to JS (prototype)-speak, and you get something like: 把它翻译成JS(原型)-speak,你会得到类似的东西:
For each function object JS creates, this object is assigned a prototype
property. 对于JS创建的每个函数对象,为该对象分配一个
prototype
属性。 The prototype
property is an instance of Object
, but it has 1 special property. prototype
属性是Object
一个实例,但它有一个特殊属性。
If one attempts to access a property or method on an object, and JS cannot find this property defined at the instance level, JS will attempt to resolve the name on the prototype property: 如果有人试图访问对象上的属性或方法,并且JS无法在实例级别找到此属性,JS将尝试解析prototype属性上的名称:
instance.nonExistantProperty;
//js scans instance variable, doesn't find property:
instance.prototype.nonExistantProperty
//js uses prototype, if not found:
instance.prototype.prototype.nonExistantProperty
//all the way up to Object.prototype, which does not have a prototype, so here an exception is raised (TypeError is thrown)
Here's a short schematic representation of this lookup, which I copied from one of my older posts here , it might be worth a look, also check the linked answers at the bottom, they go into even more details on this matter 这是这个查找的简短示意图,我从这里的一个旧帖子中复制过 ,可能值得一看,也可以查看底部的链接答案,他们会详细介绍这个问题
[ F.divide ]<=========================================================\ \
F[divide] ===> JS checks instance for property divide | |
/\ || | |
|| || --> property found @instance, return value-------------------------------| |
|| || | |
|| ===========> Function.prototype.divide could not be found, check prototype | |
|| || | |
|| ||--> property found @Function.prototype, return-----------------------| |
|| || | |
|| ==========> Object.prototype.divide: not found check prototype? | |
|| || | |
|| ||--> property found @Object.prototype, return---------------------|_|
|| || |=|
|| =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X|
|| \ /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined
That's basically it. 基本上就是这样。
Now, perhaps you're also a tad thwarted as to why Foo.prototype.constructor
references the Foo
function. 现在,也许你对于为什么
Foo.prototype.constructor
引用Foo
函数有点挫败。
Again, this is quite easy, because each instance is expected to contain all information you might require to determine which type of object you're dealing with: 同样,这很容易,因为每个实例都应包含您可能需要的所有信息,以确定您正在处理的对象类型:
function Foo{}
var inst = new Foo();
console.log(inst.constructor);//references the constructor function
Remember, all instances returned by Foo
return an object, that references all of the prototype
properties, and (optionally) some properties at instance level, too. 请记住,
Foo
返回的所有实例都返回一个对象,该对象引用所有prototype
属性,以及(可选)实例级别的某些属性。
Why, then, would you even bother creating such instances? 那么,为什么还要打扰创建这样的实例呢? Again this is perfectly simple: changing an instance, does not change the prototype:
同样,这非常简单:更改实例,不会更改原型:
console.log(Foo.prototype.constructor === inst.constructor);//true
inst.constructor = function(){};//override constructor property
console.log(Foo.prototype.constructor === inst.constructor);//false, prototype did not change
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.