与“原型”相反的是什么?

时间:2013-11-28 07:12:26

标签: javascript object prototypal-inheritance

请考虑以下事项:

var o = {foo: 'bar'};
var p = Object.create(o);

如果op原型,那么关于p的{​​{1}}是什么?

3 个答案:

答案 0 :(得分:5)

我不知道对于其原型是另一个对象的对象的正式术语有任何广泛的共识,但恕我直言,派生对象一词是可以接受的。

原型继承的关键是一个对象从另一个继承,或者从另一个对象派生。在一些经典的OO语言中,例如C ++,您将听到术语派生类,因为类继承自其他类。因为继承是在原型语言中的对象之间,我会说“派生对象”是有道理的。

答案 1 :(得分:3)

注意:实际上每个对象的原型实际上都有对构造函数的引用。所以这是错误的,尽管关于不太直接关系的观点仍然存在。原型对象仍然可以换出,但原型实际连接到对象,可以使用__proto__Object.getPrototypeOf(instance)直接访问( proto 不是标准的,因此对象。如果可用,getPrototypeOf更理想。)

我认为最好根据具有原型的对象构造函数进行思考。将Object.create视为一个如下所示的函数:

function objCreate(prototypeObject){
    var constructor = function(){};
    constructor.prototype = prototypeObject;

    return new constructor;
}

所以在:

的情况下
var o = {foo: 'bar'};
var p = objCreate(o);

o被赋值给p的构造函数的prototype属性。

现在看看这个:

alert(p.foo);//'bar'

p.constructor.prototype = { foo: 'foobiedoobie', bar: 'ubarfu' }
alert(p.foo);//'foobiedoobie' // and we could access bar if we wanted to

使用术语“派生”或其他任何断言两种类型实体之间直接关系的东西,因为你可以随时换掉p构造函数的原型属性,改变所有可用的属性p的构造函数是追溯性的。 p不是来自o。 o,直到我们更改它,如果你调用p没有的属性,则检查其属性的备份对象。然后,如果该备份对象没有它,则JS调用对象检查其构造函数的原型,依此类推。

这就是为什么我个人不喜欢Object.create或新出现的类语法。这一切都是一样的,但是我们为了一个非常小的语法糖赢而不必要地埋葬了实际上正在发生的事情,这使得我们可以很容易地产生的语法让水变得有点模糊。

那么对于o来说什么是p?

  

p是碰巧有o作为其构造函数的构造函数的实例   原型在这个时候。

那里没有直接关系。试图断言一个只会让人迷惑,他们会错过实际工作方式的真正强大之处。您无法在大多数语言中换出类,并且所有新的继承属性都可以突然调用。你可以在JS。那是因为它更像是一个备份对象链来检查不是直接在实例上设置的属性而不是继承方案。

答案 2 :(得分:0)

p将是o的原型链,而o将是p的原型链。当在实例上无法直接找到某个成员时,使用原型链。 JavaScript只会查找原型链,直到找到成员或返回undefined:https://stackoverflow.com/a/16063711/1641941

var o = {o:22}
var p = Object.create(o);
p.p = 33;
var q = Object.create(p);
console.log(q);
console.log(q.__proto__);
console.log(q.__proto__.__proto__);