3

What is o ?

If I am not mistaken, prototype means that F is going to inherit from o , but that is all I can understand here.

Can someone break this down for me:

if (!Object.create) {
  Object.create = (function () {
  var F = function(){};

  return function (o) {
    if (arguments.length !== 1) {
        throw new Error('Object.create implementation only accepts one parameter.');
    }
    F.prototype = o;
    return new F();
  };
}());
MrE
  • 19,584
  • 12
  • 87
  • 105
fish man
  • 101
  • 1
  • 7
  • There seems to be an error here: `F` is initialized only once, so every time you call `Object.create()` you change the prototype of every other object that you created with it. – Russell Zahniser Jul 31 '13 at 19:19
  • @RussellZahniser I've been scratching my head over that too. I can't get that behavior to materialize when I try it however. – Pointy Jul 31 '13 at 19:22
  • It appears that this is the [recommended polyfill from MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill), so I assume I am just missing something. – Russell Zahniser Jul 31 '13 at 19:24
  • @RussellZahniser the stuff that goes on with `new` and the prototype etc. is sufficiently bizarre that I almost never program that way :) – Pointy Jul 31 '13 at 19:26
  • @RussellZahniser, The fact that we are reusing the same empty function `F` as a constructor will not affect in any way the various created instances. Here's what happens: `F` is a function that has an initial `prototype` wich is an object that has it's prototype chain set to `Object` and which has it's constructor property set to `F`. When doing `new F()`, it creates a new `object` that has it's prototype chain set to the prototype of `F` and it runs the function `F` in the context of that new object. – plalx Jul 31 '13 at 19:30
  • @Pointy Therefore, when we assign a new `object` to `F.prototype`, it doesn't affect previously created instances, but will effectively setup the prototype chain of newly created instances so that it points to that new `object`. However, if you directly modify a property of `F.prototype`, it will affect all instances that have that object in their prototype chain. – plalx Jul 31 '13 at 19:42
  • @plalx well said :) Yes, I surmised that the essence of the matter is the operation of `new`, and that the instances must retain their relationship to the prototype that was there when they were created. It's not that it doesn't make sense, it's just that there are many "moving parts" involved. – Pointy Jul 31 '13 at 19:44
  • @plalx: Yes. What I hadn't understood there was that `new F()` essentially does `this.__proto__ = F.prototype`, not `this.__proto__ = F`. – Russell Zahniser Jul 31 '13 at 19:44
  • @RussellZahniser, Exactly ;) Therefore it's more efficient to reuse the same empty constructor over and over instead of creating a new one everytime. – plalx Jul 31 '13 at 19:48

2 Answers2

4

o is a parameter that you pass into the function.

For example:

var myObj = Object.create({
        myFn: function(){}
});

Then you can do:

myObj.myFn();
Naftali
  • 144,921
  • 39
  • 244
  • 303
2

The context of that code can help you understand it better.

This polyfill covers the main use case which is creating a new object for which the prototype has been chosen but doesn't take the second argument into account. - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill

The code is intended to serve as a replacement for Object.create(proto [, propertiesObject ]) when Object.create is not provided by the environment.

So, o is just the object which will serve as the prototype of the new object you are creating.

In practice, this means that we can use o as our superclass (or more correctly o is the prototype of our superclass).

The example from the Mozilla docs makes this clear:

//subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);

Answering the comment, this feels a little too long for the comment box:

o is the prototype of the object you want to inherit from. Technically it is an object too, everything in JS is an object. How is almost everything in Javascript an object?.

Why would you want to inherit from another object? What's the point of OOP?

What does this line do? F.prototype = o;

Lets repeat the full code, except with comments:

// if the execution environment doesn't have object.create, e.g. in old IE
if (!Object.create) {
    // make object.create equal to something
    Object.create = (function(){
        // create a new object F which can be inherited from
        function F(){}
        // return a function which 
        return function(o){
            // throw an error if 
            if (arguments.length != 1) {
                throw new Error('Object.create implementation only accepts one parameter.');
            }
            // force F to inherit o's methods and attributes
            F.prototype = o
            // return an instance of F
            return new F()
        }
    })() // this is an IIFE, so the code within is automatically executed and returned to Object.create
}
Community
  • 1
  • 1
Luqmaan
  • 2,052
  • 27
  • 34
  • 1
    so 'o' is an object.. why are they trying to inheret from it? what purpose does this code serve: F.prototype = o; – fish man Jul 31 '13 at 19:33
  • Updated answer with reply to your comment. Hope it helps you understand the code better. You should read this as well: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript – Luqmaan Jul 31 '13 at 19:47