Domanda

Consider the following:

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

If o is the prototype of p, then what is p with regard to o?

È stato utile?

Soluzione

I'm not aware that there is any widespread consensus on a formal term for the object whose prototype is another object, but IMHO the term derived object is acceptable.

The point of prototypal inheritance is that one object inherits from another, or is derived from another. In some classical OO languages, such as C++, you will hear the term derived class, because classes inherit from other classes. Because inheritance is between objects in prototypal languages, I would say that "derived object" makes sense.

Altri suggerimenti

Note: in reality every object's prototype actually has a reference to the constructor. So this is wrong-ish although the point about the not-quite direct relationship holds. The prototype object can still be swapped out but the prototype is actually connected to the object and can be accessed directly with __proto__ or Object.getPrototypeOf(instance) (proto isn't standard so Object.getPrototypeOf is more ideal if available).

I think it's better to think in terms of an object's constructor having a prototype. Think of Object.create as a function that looks like this:

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

    return new constructor;
}

So in the case of:

var o = {foo: 'bar'};
var p = objCreate(o);

o is assigned to the prototype property of p's constructor.

Now check this out:

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

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

The use of the term "derived" or anything else that asserts a direct relationship between the two kind of munges what's actually happening because you could swap out the prototype property of p's constructor any time, changing all properties available to all instances of p's constructor retroactively. p is not derived from o. o is, until we change it, the backup object whose properties get examined if you call for a property that p doesn't have. And then if that backup object doesn't have it, the JS call object checks its constructor's prototype and so on up the chain.

This is why I don't personally like Object.create or the new upcoming class syntax. It all works the same but we bury what's actually going on needlessly for a very small syntax sugar win that makes the waters a bit murkier for syntax we could easily produce ourselves.

So what is p with regard to o?

p is an instance of a constructor that happens to have o as its prototype at this time.

There is no direct relationship there. Attempting to assert one will only confuse people and they'll miss how truly powerful the way it actually works can be. You can't swap out a class in most languages and have all the new inherited properties suddenly be callable. You can in JS. That's because it's more like a chain of backup objects to check for properties not directly set on the instance with than an inheritance scheme.

p would be down the prototype chain of o and o would be up the prototype chain of p. Prototype chain is used when a certain member cannot be found directly on the instance. JavaScript will look only up the prototype chain until it finds the member or return 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__);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top