Javascript中的无限原型继承

Javascript中的无限原型继承,javascript,prototypal-inheritance,Javascript,Prototypal Inheritance,我正在学习Javascript中的原型继承,为了我的理解,我正在尝试使用它将流程发送到无限递归链接中 我对原型继承的看法是,一个对象(一个函数)拥有原型链接。该对象的任何实例都指向它。因此,如果我说instance.someproperty,它将查看父对象的原型链 假设这样,若我只是将函数原型列表指向它自己,那个么当对象试图访问某些属性时,它应该进入无限循环 var p = function(){}; p.prototype = p; // I also tried p.prototyp

我正在学习Javascript中的原型继承,为了我的理解,我正在尝试使用它将流程发送到无限递归链接中

我对原型继承的看法是,一个对象(一个函数)拥有原型链接。该对象的任何实例都指向它。因此,如果我说instance.someproperty,它将查看父对象的原型链

假设这样,若我只是将函数原型列表指向它自己,那个么当对象试图访问某些属性时,它应该进入无限循环

 var p = function(){};

 p.prototype = p;
 // I also tried p.prototype = new p();

 var q = new p();

 // and now when I say q.something, it should never be able to find it.

我想知道为什么这不起作用,以及如何使其进入无限循环。

使用更常见的样式:

function P(){};
P.prototype = P;
在ECMA-262中,由
[[Prototype]]
表示

将不同的对象分配给p.prototype不会修改p的
[[prototype]]
,因此其继承链保持为:

P : P[[Prototype]] -> Function.prototype -> Object.prototype -> null
假设p和p.prototype都指向同一个对象,那么p实例的
[[prototype]]
链是:

所以没有无止境的循环

如果没有p.prototype的分配,p的原型链将是:

p : p[[Prototype]] -> P.prototype -> Object.prototype -> null
为了得到一个无休止的循环,你可以在支持它的浏览器中将一个对象分配到它自己的
\uuuu proto\uuuu
属性(访问
[[Prototype]]]
的公共方式),但我不确定这是一个好主意,Firefox抛出:

"TypeError: cyclic __proto__ value".

那么,关于你的第一个问题:

var p = function(){};

p.prototype = p;
// I also tried p.prototype = new p();

var q = new p();
在第一个例子中,当您创建
p
的实例时,您所做的只是将原型设置为函数
p
本身,它本身就是一个对象(具有
长度
原型
等属性)。它的实际内部原型是
Function.prototype
,它又有一个
Object.prototype
的原型

第二支稍有不同——很近,但没有雪茄。当您将
new p()
分配给
p.prototype
时,
prototype
属性尚未设置,因此您只需将
prototype
属性的原始值作为实例的内部原型


继续你的第二个问题。我不明白你为什么要这样做,因为每个属性都会被它自己的实例属性所遮蔽

 var p = function(){};

 p.prototype = p;
 // I also tried p.prototype = new p();

 var q = new p();

 // and now when I say q.something, it should never be able to find it.
即使你被允许(没有浏览器允许),也没有意义

考虑这一点:

var a = { b: 1 };
a.__proto__ = a;
让我们假设这是可行的,忽略这样一个事实,即这会在所有浏览器中抛出一个TypeError(这是在即将发布的ES6规范的附录B中为浏览器指定的)

如果要访问属性
b
,就永远不会进入原型链

如果您试图访问一个不存在的属性,那么一个实现(如果它允许这样做的话)可以沿着原型链,递归地返回到它自己,或者认识到该属性永远不会被找到,并且返回未定义的属性

当然,存在涉及多个对象的情况:

var a = { x: 1 };
var b = { y: 2 };
b.__proto__ = a;
a.__proto__ = b;

然而,这太愚蠢了,没有实际用途(如果一开始允许的话,它就没有实际用途)。

原型函数本身与属性查找无关。用于学习目的?你在生活中所做的一切对你有用吗?@jfriend不做黑客没关系。但我不会因为人们有这种倾向而责怪他们。@jfriend00-在“黑客”一词中,我将继续使用一个更为经典的定义,即一个人为了理解事物的工作原理而对事物开刀。Prototype更像是一种代理查找机制,而不是真正的继承机制。了解这一点在我日常使用/实施it时起到了关键作用。这不是关于打破东西,而是理解为什么它不打破。我想他问你为什么要让小鸡过马路,而真正的问题是“天哪!它是怎么跑到另一边的?”那么我怎么才能让它无休止地循环?看这个,希望它能有所帮助:@OneKitten:我也试过:)我以为这是chrome的东西,所以我做了同样的事情,但在node.js中得到了同样的错误。后来意识到node.js也是v8:)