__proto__ 与 constructor.prototype 有何不同?

IT技术 javascript inheritance prototype-programming
2021-02-05 23:12:14
function Gadget(name, color)
{
   this.name = name;
   this.color = color;
}

Gadget.prototype.rating = 3

var newtoy = new Gadget("webcam", "black")

newtoy.constructor.prototype.constructor.prototype.constructor.prototype 

它总是返回 rating = 3 的对象。

但是,如果我执行以下操作:

newtoy.__proto__.__proto__.__proto__

链最终返回null

同样在 Internet Explorer 中,如果没有__proto__属性,我将如何检查 null

6个回答

我最近一直在努力解决这个问题,终于想出了这张“地图”,我认为它可以充分说明这个问题

http://i.stack.imgur.com/KFzI3.png 在此处输入图片说明

我知道我不是第一个编造这个的人,但弄清楚它比找到它更有趣:-)。无论如何,在那之后我发现了另一个我认为基本相同的图表:

Javascript 对象布局

对我来说最令人惊讶的是发现它Object.__proto__指向Function.prototype, 而不是Object.prototype,但我相信这是有充分理由的 :-)

如果有人想测试它,我也将图像中提到的代码粘贴到此处。请注意,一些属性被添加到对象中,以便在一些跳转后更容易知道我们的位置:

Object.O1='';
Object.prototype.Op1='';

Function.F1 = '';
Function.prototype.Fp1 = '';

Cat = function(){};
Cat.C1 = '';
Cat.prototype.Cp1 = '';

mycat = new Cat();
o = {};

// EDITED: using console.dir now instead of console.log
console.dir(mycat);
console.dir(o);
@drodsou 你的第二个链接很棒。现在请检查一下;) mollypages.org/misc/js.mp很好的解释:D
2021-03-25 23:12:14
@GiorgiMoniava 正确。Object本身就是一个函数;执行 callable 的结果Object(即 running 的返回值Object())不是函数。
2021-03-27 23:12:14
@Swivel“因此,Object() 是一个函数”-您的意思是说 Object 是一个函数吗?没有 ()
2021-04-01 23:12:14
@utsaina 非常酷。查看OP 发布的代码的另一个图形表示我认为我们的图表在技术细节方面是一致的。
2021-04-03 23:12:14
之所以Object.__proto__指向,Function.prototype是因为Object()它本身就是一个实例化一个空对象的原生函数。因此,Object()是一个函数。您会发现所有其他主要本地类型的__proto__属性都指向Function.prototype. ObjectFunctionStringNumberArray都继承了 Function 原型。
2021-04-05 23:12:14

constructor是由prototype函数对象属性指向的对象的预定义 [[DontEnum]] 属性,并且最初将指向函数对象本身。

__proto__ 相当于一个对象的内部 [[Prototype]] 属性,即它的实际原型。

当您使用new运算符创建对象时,其内部 [[Prototype]] 属性将设置为构造函数的prototype属性所指向的对象

这意味着.constructor将评估为.__proto__.constructor,即用于创建对象的构造函数,正如我们所了解的,protoype该函数属性用于设置对象的 [[Prototype]]。

.constructor.prototype.constructor.constructor(只要这些属性未被覆盖)相同;有关更详细的说明,请参见此处

如果__proto__可用,您可以遍历对象的实际原型链。在普通的 ECMAScript3 中无法做到这一点,因为 JavaScript 不是为深层继承层次结构设计的。

“此处”链接是黄金标准。如果你想要完整的描述,去那里。
2021-04-03 23:12:14
.constructor.prototype链子捕捉很好我也不清楚,虽然我没有看到它.constructor是平等的.__proto__.constructor这只是意味着在构造函数和它的原型之间循环。
2021-04-08 23:12:14

JavaScript 中的原型继承基于__proto__属性,从某种意义上说,每个对象都继承了由其__proto__属性引用的对象的内容

prototype属性仅适用于Function对象,并且仅在使用new运算符调用Functionas 构造函数时才特殊在这种情况下,创建的对象__proto__将被设置为构造函数的Function.prototype

这意味着添加到Function.prototype将自动反映所有__proto__引用Function.prototype.

Function.prototype用另一个对象替换构造函数不会更新__proto__任何已存在对象的属性。

请注意,__proto__不应直接访问属性,而应使用Object.getPrototypeOf(object)代替。

要回答第一个问题,我创建了一个定制的图表__proto__prototype参考文献,遗憾的是计算器不允许我与“不到10声誉”添加图像。也许其他时间。

[编辑] 该图使用了[[Prototype]]代替,__proto__因为 ECMAScript 规范是这样引用内部对象的。我希望你能弄清楚一切。

这里有一些提示可以帮助您理解该图:

red    = JavaScript Function constructor and its prototype
violet = JavaScript Object constructor and its prototype
green  = user-created objects
         (first created using Object constructor or object literal {},
          second using user-defined constructor function)
blue   = user-defined function and its prototype
         (when you create a function, two objects are created in memory:
          the function and its prototype)

请注意,constructor创建的对象中不存在属性,而是从原型继承的。

在此处输入图片说明

@xorcus能否请您解释这一点:new MyFunction()创建它的对象实例__proto__应该是指它的构造函数的原型被MyFunction.prototype.那么,为什么MyFunction.prototype.__proto__referes来Object.prototype它应该参考(就像我的第一个样本)到它的 ctor 的原型,它是MyFunction.prototype(注意这MyFunction.prototype是一个实例Myfunction
2021-03-22 23:12:14
@Royi Namir:MyFunction.prototype.__proto__ 指的是 Object.prototype,因为 MyFunction.prototype 是一个对象。Object.prototype 被所有对象继承(通常,这是继承的原型链结束的地方)。我不同意 MyFunction.prototype 是 MyFunction 的一个实例。obj instanceof MyFunction <=> MyFunction.prototype.isPrototypeOf(obj) <=> MyFunction.prototype 存在于 obj 原型链中。MyFunction.prototype 对象不是这种情况
2021-03-22 23:12:14

Object是夏娃,Function也是亚当,亚当(Function)用他的骨头(Function.prototype)创造了夏娃(Object)。那么谁创造了亚当(Function)?-- JavaScript 语言的发明者 :-)。

根据utsaina的回答,我想添加更多有用的信息。

对我来说最令人惊讶的是发现它Object.__proto__ 指向Function.prototype, 而不是Object.prototype,但我相信这是有充分理由的 :-)

不应该。 Object.__proto__不应该指向Object.prototype. 相反,实例Object oo.__proto__应指向Object.prototype

(请原谅我使用的条款classinstance在JavaScript,但你知道它:-)

我认为类Object本身是 的一个实例Function,这就是为什么Object.__proto__ === Function.prototype. 因此:Object是夏娃,Function也是亚当,亚当(Function)用他的骨头(Function.prototype)创造了夏娃(Object)。

此外,即使类Function本身也是它自己的一个实例Function,也就是说Function.__proto__ === Function.prototype,这也是为什么Function === Function.constructor

此外,常规类Cat是 的实例Function,即Cat.__proto__ === Function.prototype

上面的原因是,当我们在 JavaScript 中创建一个类时,实际上我们只是在创建一个函数,它应该是Function. ObjectFunction只是特殊,但他们仍然是class,而是Cat普通class。

作为一个因素,在 Google Chrome JavaScript 引擎中,有以下 4 个:

  • Function.prototype
  • Function.__proto__
  • Object.__proto__
  • Cat.__proto__

它们都===(绝对等于)其他 3 个,它们的值是function Empty() {}

> Function.prototype
  function Empty() {}
> Function.__proto__
  function Empty() {}
> Object.__proto__
  function Empty() {}
> Cat.__proto__
  function Empty() {}
> Function.prototype === Function.__proto__
  true
> Function.__proto__ === Object.__proto__
  true
> Object.__proto__ === Cat.__proto__
  true

行。那么谁创造了特殊的function Empty() {}( Function.prototype)?考虑一下:-)

我纠正了你指出的最后一件事。它们的value在于function Empty() {}谷歌浏览器。我还添加了控制台输出。
2021-03-11 23:12:14
同意,除了最后一件事:function Empty() {}你指的是什么等于Function.prototype等?,你在chrome控制台中使用的代码是什么?
2021-03-27 23:12:14
抱歉对旧线程发表评论。但它们是由语言的发明者创造的吗?
2021-03-30 23:12:14
所有的函数都是 instanceof Function,因此,所有的函数都_ _proto_ _从 Function.prototype继承 ( ) 。它是如此简单 :)
2021-04-01 23:12:14

我真的不知道为什么人们没有纠正你理解中的实际问题。

这会让你更容易发现问题

那么让我们看看发生了什么:

var newtoy = new Gadget("webcam", "black")

newtoy 
  .constructor //newtoy's constructor function is newtoy ( the function itself)
    .prototype // the function has a prototype property.( all functions has)
      .constructor // constructor here is a **property** (why ? becuase you just did `prototype.constructor`... see the dot ? )  ! it is not(!) the constructor function  !!! this is where your mess begins. it points back to the constructor function itself ( newtoy function)
         .prototype // so again we are at line 3 of this code snippet
            .constructor //same as line 4 ...
                .prototype 
                 rating = 3

太好了,现在让我们看看这个 __proto__

在此之前,请记住以下两点__proto__

  1. 当您使用new运算符创建对象时,其内部[[Prototype]]/proto__属性将设置为其prototype属性(1)constructor function或“创建者”(如果您愿意)。

  2. 在 JS 中硬编码 - :Object.prototype.__proto__null.

让我们将这 2 点称为“ bill

newtoy
     .__proto__ // When `newtoy` was created , Js put __proto__'s value equal to the value of the cunstructor's prototype value. which is `Gadget.prototype`.
       .__proto__ // Ok so now our starting point is `Gadget.prototype`. so  regarding "bill" who is the constructor function now? watch out !! it's a simple object ! a regular object ! prototype is a regular object!! so who is the constructor function of that object ? Right , it's the `function Object(){...}`.  Ok .( continuing "bill" ) does it has a `prototype` property ? sure. all function has. it's `Object.prototype`. just remember that when Gadget.prototype was created , it's internal `__proto__` was refered to `Object.prototype` becuase as "bill" says :"..will be set to the `prototype` property of   its `constructor function`"
          .__proto__ // Ok so now our satrting point is `Object.prototype`. STOP. read bullet 2.Object.prototype.__proto__ is null by definition. when Object.prototype ( as an object) was created , they SET THE __PROTO__ AS NULL HARDCODED

更好的?