繁体   English   中英

检索JS对象原型的最佳方法

[英]Best way to retrieve the prototype of a JS object

试图了解Javascript中的原型。 对于此示例:

var obj = new Function();
obj.prototype.x = "a";

为什么我从中得到不同的结果

console.log(obj.__proto__);

console.log(obj.prototype);

谢谢

根据此来源: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

Object.prototype.__proto__指向在实例化对象时用作原型的对象。

这仅表示用作创建Function对象的原型的对象是空函数,这就是为什么在输出中有function Empty() {}的原因。 您可以在这里观察它:

console.log(Function.prototype);
var func = new Function();
console.log(func.__proto__);
console.log(func.prototype);
// OUTPUT:
// function Empty() {}
// function Empty() {}
// Object {} 

__proto__一个空对象(例如var a = {}Object {}因为这是,什么被用来创建对象的基(换句话说Object.prototype被使用)。 而且prototype甚至不能作为的属性a ,因为您已经创建了一个完全空的对象,因此没有任何东西。

另请注意, __proto__现在已弃用

为什么? 我不知道,但是我从未用过,所以我不在乎:)

prototype是另一回事,例如

Object prototype object更改将传播到所有对象,除非经受这些更改的属性和方法沿原型链进一步被覆盖。

这就是为什么您需要prototype并且在现实生活中不关心__proto__ 如果我写错了,请告诉我__proto__有用用法。

希望现在更清楚。 并回答您的原始问题:

只能通过使用prototype属性来检索JS对象的prototype ,因为__proto__包含其他内容。 如果不存在prototype属性,那么即使在实例化过程中使用了sth,也不会存在JS对象的原型。

在:

> var obj = new Function();

创建一个新的函数对象,该对象的内部[[Prototype]] (或支持它的浏览器中的__proto__ )引用Function.prototype ,即内置Function构造函数的公共原型,并分配给变量obj

因为obj是一个Function对象,所以默认情况下它具有prototype属性,以防万一它被用作构造函数。

在:

> obj.prototype.x = "a";

新的x属性将添加到obj.prototype中 ,该属性被分配了字符串'a' 请注意,默认情况下, obj仅具有prototype属性,因为它是Function对象。

所以:

obj.prototype === obj.__proto__

本质上是:

obj.prototype === Function.prototype

这显然是错误的。

因此,要回答“检索JS对象原型的最佳方法”的问题,则可以通过其原型属性访问构造函数的公共原型。

您可以使用ES5 Object.getPrototypeOf来访问实例的内部[[Prototype]] ,但是可能并非在所有地方都支持该实例。

您还可以使用受支持的非标准__proto__来访问实例的内部[[Prototype]]

更为通用的解决方案是在创建实例时保留对构造函数原型的引用(因为在以后的某个阶段更改构造函数的原型不会更改已经创建的实例的[[Prototype]] )。

因此,在一般情况下,您可以这样做:

function Foo() {
  this.internalProto = Foo.prototype;
}

var foo = new Foo();

// ES5, where supported
Object.getPrototypeof(foo) == Foo.prototype; // true

foo.internalProto == Foo.prototype; // true

// Non–standard, Where supported
foo.internalProto == foo.__proto__;     // true

根据MDN ,obj .__ proto__尚未标准化。

因此,尽管obj.prototype在所有浏览器中都有明确的标准化行为,但obj .__ proto__在不同浏览器中的行为有所不同。

您正在横向看...

.prototype.__proto__是同一对象(或在某个特定时间点)...

BUUUUUT它们是不同对象的属性。

var Human = function (name) {
    this.num_eyes = 2;
    this.num_heads = 1;
    this.name = name;
};
Human.prototype.die = function () { this.isAlive = false; };

var herman = new Human("Herman");

herman.__proto__.die === Human.prototype.die; // true

.__proto__是指向CONSTRUCTOR .prototype的链接(通常是SAME对象)

几乎是这样的:

var Human = function () {
    this = {};
    this.num_eyes = 2;
    // ......
    this.__proto__ = Human.prototype;
};

那不是构造函数的确切工作方式,但实际上就是这个想法。
这就是为什么.__proto__.prototype不是同一回事。
因为您找错了地方。

因此,如果:

var herman = new Human();
herman.__proto__ === Human.prototype;
var Human = new Function ();

...因此逻辑规定Human.__proto__ === Function.prototype;

...并且如果HumanFunction不是同一对象,则它们的.prototype属性将不会相同(除非您用另一个Human.prototype = Function.prototype; Human.__proto__ === Human.prototype; //true

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM