使用constructor.prototype遍历原型链
Traversing prototype chain using constructor.prototype
如果我可以使用obj.constructor.prototype
来访问对象的原型,那么为什么我不能使用obj.constructor.prototype.constructor.prototype
来遍历原型链,而必须使用Object.getPrototypeOf
呢?
function MyConstructor()
{
this.prop = 1;
}
var o = new MyConstructor();
console.log(o.constructor.prototype) // MyConstructor
console.log(o.constructor.prototype.constructor.prototype) // MyConstructor?
它不应该返回MyConstructor的原型function() { [native code] }
(在Chrome控制台中)吗?
所有构造函数都是全局Function
对象的实例:
function Foo(){ this.x = 1 }; // Dummy constructor function
console.log(Foo instanceof Function) // => true; Foo is an instance of global Function constructor
所有原型都是全局Object
对象的实例:
console.log(Foo.prototype instanceof Object); // => true
当定义构造函数Foo
时,它会自动附加一个Foo.prototype
对象,您可以将其视为"空白"对象,如上所述,该对象本身继承自全局Object
对象。换句话说,Foo.prototype
的原型是Object.prototype
:
function Foo(){ this.x = 1 }; // Dummy constructor function
console.log(Foo.prototype); // Foo (object); already exists
console.log(Object.getPrototypeOf(Foo.prototype) === Object.prototype); // => true
由于Foo.prototype
是一个空白对象,因此它的构造函数应该是全局Object
构造函数:
function Foo(){ this.x = 1 }; // Dummy constructor function
console.log(Foo.prototype.constructor) // => function Foo() { this.x = 1; } ??
console.log(Foo.prototype.constructor === Object.prototype.constructor); // => false
但是,这个"空白"对象有一个显式的自引用constructor
属性,它指向function Foo(){ this.x = 1 }
,并覆盖或"屏蔽"您期望的默认构造函数属性:
function Foo(){ this.x = 1 }; // Dummy constructor function
delete Foo.prototype.constructor; // Delete explicit constructor property
console.log(Foo.prototype.constructor) // => function Object() { [native code] }
console.log(Foo.prototype.constructor === Object.prototype.constructor); // => true
因此,不能递归地使用obj.constructor.prototype
遍历原型链,必须依赖Object.getPrototypeOf()
方法。
这是一个很好的视觉参考。
如果我可以使用obj.structor.prototype访问对象的原型
一般情况下你不能。考虑一下这种方法是如何工作的:
var proto = MyConstructor.prototype;
// has an (nonenumberable) property "constructor"
proto.hasOwnProperty("constructor"); // `true`
// that points [back] to
proto.constructor; // `function MyConstructor() {…}`
正如你所看到的,这是一个圆形的属性结构。当你做
var o = new MyConstructor();
// and access
o.constructor; // `function MyConstructor() {…}`
// then it yields the value that is inherited from `proto`
// as `o` doesn't have that property itself:
o.hasOwnProperty("constructor"); // `false`
但这只适用于像o
这样的对象,这些对象从原型对象继承了constructor
属性,并且在指向原型对象的情况下具有有用的值。想想
var o = {};
o.constructor = {prototype: o};
哎呀。访问o.constructor.prototype
在这里产生o
本身,它可能是任何其他无意义的值。实际上,MyConstructor.prototype
的结构与上面的相同,如果您访问proto.constructor.prototype.constructor.prototype[.constructor.prototype…]
,您将不会得到除proto
之外的任何其他内容。
那么为什么我不能使用
obj.constructor.prototype.constructor.prototype
来遍历原型链,而必须使用Object.getPrototypeOf
呢?
因为您被困在循环结构中,因为MyConstructor.prototype
)本身具有constructor
属性,而不是从Object.prototype
继承的。为了真正获得下一个对象——真正的原型链,您必须使用Object.getPrototypeOf
。
var o = new MyConstructor(); console.log(o.constructor.prototype) // MyConstructor
实际上应该是MyConstructor.prototype
。Chrome控制台有时会在显示未命名对象的有用标题时感到困惑,而且并不总是正确的。
如果你得到它的原型,它应该产生Object.prototype
,当你得到MyConstructor
函数本身的原型时,它应该是Function.prototype
。请注意,您可以通过MyConstructor.constructor.prototype
再次执行后者…
- 循环遍历以数组为值的Javascript对象
- 遍历类元素数组,并在jquery中选择同级元素
- Jquery遍历表元素
- Chrome扩展:遍历不同的页面并收集数据
- 如何遍历包含对象的数组-javascript
- 遍历 JSON 对象并检查 URL 是否以某个值结尾
- 遍历AngularJs中的对象
- JQuery 遍历当前 SELECT 值
- 循环遍历包含另一个表单的表单
- 使用Yadda和Protractor重用步骤定义,遍历所需文件
- 遍历D3中所有数据点之间的所有值
- 自动遍历所有链接的事件
- JS.循环遍历多维数组,以计数元素在每列中的出现次数
- 若将Array对象添加到Array原型中,则不遍历该对象的函数
- 数组上的 for.in 循环也会遍历原型函数
- 原型/对象语句和链遍历需要澄清
- 为什么for.in循环不遍历对象's原型
- 使用constructor.prototype遍历原型链
- 是否有一个等于hasOwnProperty()的方法可以遍历原型链
- 如何遍历对象的原型链中的所有属性