2

Javascript - The Definitive Guide (6ed) shows the following code:

Originally we have this function

/*
* Copy the enumerable properties of p to o, and return o.
* If o and p have a property by the same name, o's property is overwritten.
* This function does not handle getters and setters or copy attributes.
*/
 function extend(o, p) {
       for(prop in p) { // For all props in p.
           o[prop] = p[prop]; // Add the property to o.
      }
      return o;
}

Then the author decided to rewrite it and extend the copy ability (able to copy accessor properties, for example):

/*
* Add a nonenumerable extend() method to Object.prototype.
* This method extends the object on which it is called by copying properties
* from the object passed as its argument. All property attributes are
* copied, not just the property value. All own properties (even non-
* enumerable ones) of the argument object are copied unless a property
* with the same name already exists in the target object.
*/
Object.defineProperty(Object.prototype,
    "extend", // Define Object.prototype.extend
    {
        writable: true,
        enumerable: false, // Make it nonenumerable
        configurable: true,
        value: function(o) { // Its value is this function
           // Get all own props, even nonenumerable ones
           var names = Object.getOwnPropertyNames(o);
           // Loop through them
           for(var i = 0; i < names.length; i++) {
            // Skip props already in this object
            if (names[i] in this) continue;
            // Get property description from o
            var desc = Object.getOwnPropertyDescriptor(o,names[i]);
            // Use it to create property on this
            Object.defineProperty(this, names[i], desc);
            }
    }
});

I don't understand why we are extending Object.prototype, and now how do we use this to copy all the attributes in Object y to Object x? How do I use Object.prototype.extend ?

I decided to test if I can do something quicker. I don't understand why the following custom code doesn't work.

function extend(o){
    var p = new Object();
    for( prop in o)
        Object.defineProperty(p,prop,Object.getOwnPropertyDescriptor(o,prop));
    return p;

}


 // Let's perform a simple test

var o = {};

Object.defineProperty(o, "x", { value : 1,
   writable: true,
   enumerable: false,
   configurable: true});

o.x; // => 1
Object.keys(o) // => []

var k = new Object(extend(o));  // Good, k.x => 1

// More test

Object.defineProperty(o, "x", { writable: false });
Object.defineProperty(o, "x", { value: 2 });
Object.defineProperty(o, "x", { get: function() { return 0; } });
o.x // => 0 

// Perform the creation again

var k = new Object(extend(o));   // bad. k.x is 1, not 0

 // so the getter property didn't copy to k !!!

Sorry I am pretty new to Javascript. Thanks for the help in advance. All these questions are related to the transformation / rewrite of the function "extend"


I edited the my test code. Sorry!

CppLearner
  • 16,273
  • 32
  • 108
  • 163
  • 1
    A fairly famous example of `extend()` (check the jQuery source for how this works): http://api.jquery.com/jQuery.extend/ and http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery – Jared Farrish Aug 11 '11 at 22:56

2 Answers2

3

The purpose of defining this in the prototype is so that every Object can call it as a member function, like this:

yourobject.extend(anotherObject);

Most coders find that more elegant than having to pass both objects as parameters, like this:

extend(yourObject, anotherObject);

Modifying prototypes is a great way to add useful "methods" to objects.

side note: I would not recommend using the author's extend code. It doesn't properly check hasOwnProperty.

Jacob
  • 77,566
  • 24
  • 149
  • 228
1

You seem to misunderstand the use of prototype. Prototyping is JavaScript's way of dealing with inheritance. The extend function is terminology loaned from languages like C++ and Java and is not native to JavaScript.

Here's a guide on prototype: http://mckoss.com/jscript/object.htm

I have several years experience writing JavaScript and I'd recommend not using prototyping at all. JavaScript has other ways of dealing with data modeling that I find more elegant. It's still useful to understand how prototyping works though because it deepens your understanding of Objects.

Halcyon
  • 57,230
  • 10
  • 89
  • 128