gpt4 book ai didi

Javascript __proto__ - 澄清?

转载 作者:搜寻专家 更新时间:2023-11-01 04:17:59 27 4
gpt4 key购买 nike

我有这个功能:

函数 Foo(){}

根据这张图片:

enter image description here

>> Foo.prototype   ->    Foo {}

enter image description here

所以如果我写:

Foo.prototype.constructor

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

enter image description here

一切正常。

那么问题在哪里呢?

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

Foo{} 的构造函数是谁?

它是 function Foo(){}

你可以在这里看到它是黄色的:

enter image description here

好的

但有人告诉我here那:

enter image description here

所以 Foo.prototype.__proto__ 应该引用 function Foo(){}prototype 而不是 Object。原型(prototype) !

如果我翻译它:

    __proto__               is the                   ctor's                        prototype
_________________________________________________________________________________________
Foo.prototype.__proto__ is the function Foo(){} Foo.prototype

但这是错误的

我可能错了,因为:

enter image description here

我错过了什么?

最佳答案

注意:首先,__proto__ 是非标准的,使用 Object.getPrototypeOf,虽然为了简短,而且因为我很懒,我确实使用了prototype 在这个答案中出现了很多次

好吧,如果我没看错的话,你会被最初的假设所抛弃:

Foo.prototype -> Foo{}

根据定义,Foo 的原型(prototype)(它是一个构造函数)是 Foo 的一个实例。但是,因为构造函数是一个函数,并且构造函数返回一个特定实例的对象,所以无论哪种方式,原型(prototype)都将是一个增强的 Object
我不太喜欢将原型(prototype)继承与经典 OOP 进行比较,但可以这样想:

Foo 原型(prototype)是一种可变类定义(您可以在进行过程中添加方法和属性),构造函数创建一个增强该原型(prototype)的对象,并在实例级别添加另一层属性/方法。
因此 Foo.prototype instanceof Foo 为真。但是,Foo 是一个对象:

Object.getPrototypeOf(Foo.prototype) === Object.prototype

是真的。正如

Object.getPrototypeOf(Array.prototype) === Object.prototype.

将其翻译成 JS(原型(prototype))-speak,您会得到如下内容:

对于 JS 创建的每个函数对象,该对象都被分配了一个 prototype 属性。 prototype 属性是 Object 的实例,但它有 1 个特殊属性。
如果试图访问一个对象的属性或方法,而 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)

这是我从 one of my older posts here 中复制的此查找的简短示意图。 , 可能值得一看,也可以查看底部的链接答案,他们对此事进行了更详细的介绍

[      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

基本上就是这样。

现在,对于为什么 Foo.prototype.constructor 引用 Foo 函数,您可能也有点受挫。
同样,这很容易,因为每个实例都应该包含您可能需要的所有信息,以确定您正在处理的对象类型:

function Foo{}
var inst = new Foo();
console.log(inst.constructor);//references the constructor function

请记住,Foo 返回的所有实例都返回一个对象,该对象引用所有 prototype 属性,以及(可选)实例级别的一些属性。

那么,您为什么还要费心创建这样的实例呢?同样,这非常简单:更改实例不会更改原型(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__ - 澄清?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19677348/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com