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