Javascript proto与constructor.prototype有何不同?

Javascript proto与constructor.prototype有何不同?,javascript,inheritance,prototype-programming,Javascript,Inheritance,Prototype Programming,它总是返回额定值为3的对象 但如果我做了以下事情: 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

它总是返回额定值为3的对象

但如果我做了以下事情:

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 
链最终返回
null

[].__proto__ === Array.prototype
// true

({}).__proto === Object.prototype
// true

此外,在Internet Explorer中,如果没有
\uuuu proto\uuuu
属性,我将如何检查空值?

构造函数是函数对象的
prototype
属性指向的对象的预定义[[DontEnum]]属性,最初将指向函数对象本身

\uuuu proto\uuuu
相当于对象的内部[[Prototype]]属性,即其实际原型

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

这意味着
.constructor
将计算为
\uuuu proto\uuuu.constructor
,即用于创建对象的构造函数,如我们所知,此函数的
Prototype
属性用于设置对象的[[Prototype]]

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


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

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

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

最让我惊讶的是发现
对象。uuu proto\uuuu
指向
函数.prototype
,而不是
对象.prototype
,但我相信这有一个很好的理由:-)

如果有人想测试它,我也会在这里粘贴图片中提到的代码。请注意,一些属性被添加到对象中,以便于在一些跳跃之后知道我们在哪里:

newtoy.__proto__.__proto__.__proto__

对象
是夏娃,
函数
是亚当,亚当(
函数
)用他的骨头(
函数.原型
)创造夏娃(
对象
)。那么谁创建了Adam(
函数
)?——JavaScript语言的发明者:-)。

根据乌塞纳的回答,我想添加更多有用的信息

最让我惊讶的是发现了
对象
指向
函数.prototype
,而不是
对象.prototype
,但我 当然有一个很好的理由:——)

不应该这样<代码>对象。uuu proto_uuu
不应指向
对象。prototype
。相反,
Object
o
o.\uuu proto\uu
的实例应该指向
Object.prototype

var toy = new Gadget();
(请原谅我在JavaScript中使用术语
实例
,但您知道:-)

我认为类
对象
本身就是
函数
的一个实例,这就是
对象的原因。因此:
对象
是夏娃,
函数
是亚当,亚当(
函数
)用他的骨头(
函数.原型
)创造夏娃(
对象

此外,即使类
函数
本身也是
函数
本身的一个实例,即
函数。uuu proto\uuu==Function.prototype
,这也是
函数===Function.constructor

此外,常规类
Cat
Function
的实例,即
Cat.\uu proto\uu===Function.prototype

var toy = new Gadget();
上面的原因是,当我们在JavaScript中创建一个类时,实际上,我们只是在创建一个函数,它应该是
function
的一个实例
Object
Function
只是特殊的,但它们仍然是类,而
Cat
是常规类

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

  • Function.prototype
  • Function.\uuuuu proto\uuuuuu
  • Object.\uuuu proto\uuuu
  • Cat.\uuuu proto\uuuu
它们都是
==
(绝对相等)其他3个,它们的值是
function Empty(){}

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);

嗯。那么是谁创建了特殊的
函数Empty(){}
function.prototype
)呢?想想看:-)

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

prototype
属性仅适用于
Function
对象,并且仅当使用
new
操作符调用
函数作为构造函数时才有效。在这种情况下,创建的对象的
\uuuuu proto\uuuu
将设置为构造函数的
函数。prototype

var toy = new Gadget();
这意味着添加到
函数.prototype
将自动反映在其
\uuuuu proto\uuuu
引用
函数.prototype
的所有对象上

var toy = new Gadget();
将构造函数的
函数.prototype
替换为另一个对象将不会更新任何现有对象的
\uuuuuuuuuuuuuu
属性

请注意,不应直接访问
\uuuu proto\uuu
属性,而应使用该属性

为了回答第一个问题,我创建了一个定制的
\uuuu proto\uuuu
prototype
参考图
var toy = new Gadget();
toy
.constructor    // Gadget
.prototype    // {constructor: Gadget}
.constructor    // Gadget
.prototype    // {constructor: Gadget}
// ...
[].__proto__ === Array.prototype
// true

({}).__proto === Object.prototype
// true
toy
.__proto__    // Gadget.prototype (object looking like {constructor: Gadget})
.__proto__    // Object.prototype (topmost object in JS)
.__proto__    // null - Object.prototype is the end of any chain
var dict = Object.create(null);