5

我对使用 object.create 而不是经典的 js 方式来实现原型继承非常陌生。

至少在 Chrome 中,我很惊讶地看到以下代码:

var baseObject = {
test : function(){
    console.log('Child');
}
}

var newObject = Object.create(baseObject);
newObject.test = function(){
console.log('Parent');
this.__proto__.test();
}
console.log(newObject);

newObject.test();

产生这个(模拟网络工具中的输出):

Object {test: function, test: function} 
    test: function (){
    __proto__: Object
        test: function (){
        __proto__: Object
Parent
Child 

所以你看到它没有设置原型,而只是“__proto__”,我认为不鼓励使用它。您可以在我的代码中看到,我能够正确继承并调用父对象,但只能使用“__proto__”。使用“原型”会导致错误(未定义)。

这里发生了什么?我认为 object.create 会设置“原型”,因为这是标准(或者我假设)。为什么它会填充并让我使用“__proto__”

4

3 回答 3

5

不鼓励使用__proto__设置原型继承,因为它是非标准的。这并不意味着您不能使用Object.create()特定原型对象来制作新对象。

默认情况下,对象没有.prototype属性。您混淆.prototype了函数的对象。

所以如果我有这样的功能:

function Foo() {

}

Foo函数对象具有.prototype引用一个对象的属性,该对象将用作在__proto__作为构造函数调用时创建的任何对象的 。

var f = new Foo();

所以 nowf是一个Foo.prototype在其原型链中的对象。Object.getPrototypeOf()您可以使用;来验证这一点

Object.getPrototypeOf(f) === Foo.prototype; // true

使您Object.create能够建立相同的原型链,但不使用构造函数。所以这将是等价的。

var f2 = Object.create(Foo.prototype);

现在我们有一个对象,它的设置方式与原始f对象相同。

Object.getPrototypeOf(f2) === Foo.prototype;            // true
Object.getPrototypeOf(f2) === Object.getPrototypeOf(f); // true

所以这只是一种不同的方式来做最终相同的事情。对象与其原型链之间的关系是一种内部关系。非标准__proto__只是暴露了这种关系。

于 2013-03-05T21:15:37.277 回答
0

实例的__proto__属性应该与构造函数的 prototype属性相同。

当一个对象被创建时,它的__proto__属性被设置为引用与其内部相同的对象[[Prototype]](即它的构造函数的prototype对象)。分配一个新值__proto__也会更改内部[[Prototype]]属性的值,除非对象是不可扩展的。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/proto#Description

于 2013-03-05T21:15:48.827 回答
0

Object.create()设置该特定对象实例的原型。 prototype是构造函数的一个属性,它是自动分配为 [[Prototype]] 的对象,该对象是通过使用new具有该构造函数的运算符创建的每个实例。

__proto__是访问特定实例的 [[Prototype]] 的非标准方式。您还可以调用Object.getPrototypeOf(this)以获取访问原型的标准方法。

于 2013-03-05T21:17:17.827 回答