试图了解Javascript中的原型。对于这个例子:
var obj = new Function();
obj.prototype.x = "a";
为什么我会从
获得不同的结果console.log(obj.__proto__);
和
console.log(obj.prototype);
由于
答案 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;
...如果Human
和Function
不是同一个对象,那么他们的.prototype
属性将不会相同(除非你用另一个覆盖一个) Human.prototype = Function.prototype; Human.__proto__ === Human.prototype; //true