Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Beget function in JavaScript: The Good Parts

Tags:

javascript

I am reading JavaScript: The Good Parts. In the book, a beget function is defined. Its purpose is to create and return a new object, which uses the other object as its prototype. Why does the beget function instantiate a new function instead of an object?

if( typeof Object.beget !== 'function' ){
    Object.beget = function(o){
          var F =new Function(){}; // this line, why it cannot be var F = new Object();
          F.prototype = o;
          return new F();
    }
}
like image 490
felix Avatar asked Jul 23 '11 09:07

felix


2 Answers

This has everything to do with the new keyword. In JavaScript, new only works with functions (which are a special type of object).

  • If you use new on just about any function, you will get an object back.

    alert(typeof console.log); // function
    var dumb = new console.log();  // dumb is an object
    
  • The type of object you get back depends on that function's prototype object.

    alert(typeof console.log.prototype); // object, any new objects created by the new keyword will be of this type.
    alert(typeof Function.prototype); // function, new objects are functions.
    alert(typeof new Function()); // function, see?
    alert(typeof (function(){})); // function, using literal syntax, equivalent
    
  • You may have noticed from above that Function itself is a function. In fact, all of the built-in constructors are functions (Function, Object, Number, Array, etc). Capitalization is just a convention to distinguish how you use a function.

So to get back to your question, the author uses an empty Function object simply because it can be used as a constructor. Objects cannot. He then changes the constructor's prototype, so that it will return objects of that type.

Object.beget = function(o) {
    var F = new Function(); // now F can be used as a constructor. 
    F.prototype = o; // All new objects F creates will be based on o.
    return new F();
};
like image 94
Brian Duncan Avatar answered Nov 01 '22 17:11

Brian Duncan


To add on to previous answers and avoid some confusion, this beget() function was replaced with create() via an errata, so different books seem to have different version of the code. The book on Safari Books Online has it printed like this:

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        var F = function () {};
        F.prototype = o;
        return new F();
    };
}

Note that it no longer encourages the use of the new keyword on line 3.

like image 5
mikhail Avatar answered Nov 01 '22 16:11

mikhail