Javascript __proto__ - 澄清? [英] Javascript __proto__ - clarification?

查看:130
本文介绍了Javascript __proto__ - 澄清?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个功能:



function Foo(){}



根据这张图片:



 >> Foo.prototype  - > Foo {} 



所以如果我写:



Foo.prototype.constructor



现在 - 它对构造函数的引用,它创建了 Foo {} 对象,该对象是 function Foo(){}





一切正常。



那么问题在哪里?



Foo.prototype 是一个对象实例 - > Foo {}



谁是 Foo {} 的构造函数?



它是函数Foo(){}



你可以在这里看到黄色:





确定



但我被告知,可能值得一看,也查看底部的链接答案,他们会详细讨论此事

  [F.divide]< ===================================== ==================== \ \ 
F [divide] ===> JS检查实例的属性划分| |
/ \ || | |
|| || - >找到属性@instance,返回值------------------------------- | |
|| || | |
|| ===========>无法找到Function.prototype.divide,检查原型| |
|| || | |
|| || - >找到属性@ Function.prototype,返回----------------------- | |
|| || | |
|| ==========> Object.prototype.divide:未找到检查原型? | |
|| || | |
|| || - >找到@ Object.prototype属性,返回--------------------- | _ |
|| || | = |
|| =======>原型为null,返回undefined.divide~~~~~~~~~~~~~~~ | X |
|| \ /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TypeError无法读取未定义的属性'x'

这基本上就是它。



现在,对于为什么 Foo.prototype.constructor 引用 Foo,你可能也有点挫败/ code> function。

同样,这很容易,因为每个实例都应包含您可能需要的所有信息,以确定您正在处理的对象类型:

  function Foo {} 
var inst = new Foo();
console.log(inst.constructor); //引用构造函数

记住, Foo 返回的所有实例都返回一个对象,该对象引用所有原型属性,以及(可选)某些属性实例级也是如此。



那么,为什么还要打扰创建这样的实例呢?同样,这非常简单:更改实例,不会更改原型:

  console.log(Foo.prototype.constructor = == inst.constructor); // true 
inst.constructor = function(){}; //覆盖构造函数属性
console.log(Foo.prototype.constructor === inst.constructor); // false,原型没有改变


I have this function :

function Foo(){}

According to this picture :

>> Foo.prototype   ->    Foo {}

So if I write :

Foo.prototype.constructor

Now - it references to the constructor function which created the Foo{} object which is function Foo(){}

All ok.

So where is the question ?

Foo.prototype is an object instance --> Foo {}

And who is the constructor function of Foo{} ?

it is the the 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 !

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

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. 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.
I'm not a big fan of comparing prototypal ineritance to classical OOP, but think of it like this:

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.
Hence Foo.prototype instanceof Foo is true. But, Foo being an object:

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:

For each function object JS creates, this object is assigned a prototype property. The prototype property is an instance of Object, but it has 1 special property.
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:

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.
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.

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

这篇关于Javascript __proto__ - 澄清?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆