8

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?

user3025492
  • 2,853
  • 4
  • 18
  • 19
  • 2
    @yuan I initially reached for that wording, but the prototype *isn't* the "constructor". That is, `p instanceof o` throws a TypeError. – user2864740 Nov 28 '13 at 07:14
  • 1
    Indeed. `p instanceof o` is a `TypeError`. – Amadan Nov 28 '13 at 07:15
  • @Amadan but that doesn't make anysense. that's practically what instanceof means, is it not? – user3025492 Nov 28 '13 at 07:56
  • or is it only for constructor function-constructed objects? – user3025492 Nov 28 '13 at 07:56
  • Are you just looking for a name? I would call them a 'specialization' – woolstar Nov 28 '13 at 08:27
  • Deleted a comment I made for not being 100% accurate. Objects do not have constructor properties. Common misconception on my part. Their prototypes do. And then constructors reference the prototype that had a reference to them. Cripes that's confusing but it's the reason you can't climb the constructor/prototype tree just by referencing constructor.prototype.constructor.prototype which is a faulty assumptions I made in some other recent answer. – Erik Reppen Dec 03 '13 at 04:24

3 Answers3

5

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.

Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • 1
    I would not use the term derived object for the reasons elaborated upon in my answer. – Erik Reppen Nov 28 '13 at 08:15
  • @ErikReppen I did upvote your answer, but my answer here was meant to be independent of JS (no consideration of constructors). When an object is "created" *from* a prototype it's a kind of derivation: you _derive_ a circle from a prototypical circle. It's true in JS, which has a prototype property on every function that is used for the proto of objects created with the function, you can dynamically change the nature of "types". And I do believe that in JavaScript, `new` is better than `Object.create`. Still, `Object.create` does say "make me a new object like this existing one" – Ray Toal Nov 28 '13 at 20:32
  • I'm not super-familiar with prototypal outside of JS but I believe that's a fair point in the broader context where properties are cloned rather than attached through a call-object referencing an existing object. – Erik Reppen Nov 28 '13 at 21:03
4

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.

Erik Reppen
  • 4,605
  • 1
  • 22
  • 26
  • Object.create actually makes things much clearer when you abandon the classical inheritance approach. If your object needs a constructor, add a "create" method which does Object.create(this) and initializes. No need for the mess of attaching prototypes to constructors. – rich remer Jul 19 '14 at 19:48
  • Or you could a create method that does the thing that Object.create does : ). I'm not really a hater though. I'd just rather the effort went towards something more horrifying to keep the protectionist coder riffraff away like operator overloading or something. – Erik Reppen Jul 23 '14 at 02:59
0

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__);
Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • I was asking about nomenclature. – user3025492 Nov 28 '13 at 07:55
  • @user3025492 Not sure if using derived is a good term either. It keeps you thinking of class based terms. But I guess you can call it anything you want because most JS programmers are blissfully unaware of it's existence anyway: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain – HMR Nov 28 '13 at 08:38