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

时间:2014-01-15 23:32:24

标签: javascript prototype

试图了解Javascript中的原型。对于这个例子:

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

为什么我会从

获得不同的结果
console.log(obj.__proto__);

console.log(obj.prototype);

由于

4 个答案:

答案 0 :(得分:2)

根据此消息来源: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对象的原型,因为__proto__包含不同的属性。如果prototype属性不存在,则没有JS对象的原型,即使在实例化过程中使用了sth。

答案 1 :(得分:2)

在:

> var obj = new Function();

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

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

在:

> obj.prototype.x = "a";

将新的 x 属性添加到 obj.prototype ,并为其指定字符串'a'的值。请注意, obj 默认只有一个prototype属性,因为它是一个Function对象。

所以:

obj.prototype === obj.__proto__

基本上是:

obj.prototype === Function.prototype

显然是假的。

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

您可以使用ES5 Object.getPrototypeOf访问实例的内部[[Prototype]],但在任何地方都可能不受支持。

您还可以使用支持的非标准[[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

答案 2 :(得分:0)

MDN,obj .__ proto__的协调尚未标准化。

因此,虽然obj.prototype在浏览器中具有明确的标准化行为,但obj .__ proto__在不同的浏览器中表现不同。

答案 3 :(得分:0)

你正在侧身看......

.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