John Resig wrote: > I wanted to bring up some further evidence for the widespread use of an > extend() method.
I always need both these functions. However my ObjectClone function is just a single statement that calls the other function: return ObjectMerge (Source, {}). So I see Clone as trivial syntactic sugar. Merge is necessary and costs work and processing time. Ingvar > Here are the top 5 JavaScript libraries and their associated versions of > "Object.extend()": > > > == jQuery.js: > > (jQuery also does deep extend - but that isn't relevant here.) > > jQuery.extend = jQuery.fn.extend = function() { > var target = arguments[0] || {}, i = 1, length = arguments.length, > options; > > if ( typeof target != "object" && typeof target != "function" ) > target = {}; > > if ( length == i ) { > target = this; > --i; > } > > for ( ; i < length; i++ ) { > if ( (options = arguments[ i ]) != null ) { > for ( var name in options ) { > target[ name ] = options[ name ]; > } > } > } > > return target; > }; > > > == Prototype.js: > > Object.extend = function(destination, source) { > for (var property in source) > destination[property] = source[property]; > return destination; > }; > > == Mootools.js: > > var $extend = function(){ > var args = arguments; > if (!args[1]) args = [this, args[0]]; > for (var property in args[1]) args[0][property] = args[1][property]; > return args[0]; > }; > > == Dojo Toolkit: > > dojo._mixin = function(obj, props){ > var tobj = {}; > for(var x in props){ > if(tobj[x] === undefined || tobj[x] != props[x]){ > obj[x] = props[x]; > } > } > // IE doesn't recognize custom toStrings in for..in > if(d["isIE"] && props){ > var p = props.toString; > if(typeof p == "function" && p != obj.toString && p != > tobj.toString && > p != "\nfunction toString() {\n [native code]\n}\n"){ > obj.toString = props.toString; > } > } > return obj; // Object > } > > dojo.mixin = function(obj){ > for(var i=1, l=arguments.length; i<l; i++){ > d._mixin(obj, arguments[i]); > } > return obj; // Object > } > > == Yahoo UI: > > YAHOO.lang.augmentObject = function(r, s) { > if (!s||!r) { > throw new Error("Absorb failed, verify dependencies."); > } > var a=arguments, i, p, override=a[2]; > if (override && override!==true) { // only absorb the specified > properties > for (i=2; i<a.length; i=i+1) { > r[a[i]] = s[a[i]]; > } > } else { // take everything, overwriting only if the third parameter > is true > for (p in s) { > if (override || !(p in r)) { > r[p] = s[p]; > } > } > > L._IEEnumFix(r, s); > } > }; > > There are a couple points that are very important here: > 1) They all extend the base object with the enumerable properties at least > one other object. > 2) There is very little done to prevent properties coming in from > [SomeObject].prototype - this is mostly because libraries opt not to use > .hasOwnProperty() in favor of speed and/or cross-browser compatibility (older > versions of Safari and IE Mac don't have hasOwnProperty). > 3) A couple of the implementations take multiple source objects with which to > extend the base object. > > The implementations in the libraries don't deal with nearly as many edge > cases as they should (such as the aforementioned hasOwnProperty - or getters > and setters) which is something that can be done in a language > implementation. A language implementation of .extend() should certainly also > allowing non-enumerable properties to be extended, as well (considering that > this wont be possible - or will be very difficult to implement - from a > pure-script perspective). > > While Object.clone will certainly be useful in, and of, itself - it's not a > replacement for an extend method. > > I have a pure-JavaScript version of Object.extend() that I'm working on - and > I'm building a test suite for it, as well (to make sure all edge cases are > properly defined and handled): > http://ejohn.org/files/object-extend.js > > I'll be updating this file throughout the day. I'll post back when I feel as > if I have a reasonable test suite. > > --John > > ----- Original Message ----- > From: "Allen Wirfs-Brock" <[EMAIL PROTECTED]> > To: "Robert Sayre" <[EMAIL PROTECTED]>, "Mark S. Miller" <[EMAIL PROTECTED]> > Cc: "es3 x-discuss" <[EMAIL PROTECTED]>, es4-discuss@mozilla.org > Sent: Wednesday, July 16, 2008 7:10:21 PM GMT -05:00 US/Canada Eastern > Subject: RE: ES3.1 Object static methods rationale document > > As far as I can recall, we didn't discuss a specific formulation that > corresponds to Object.extend but we have considered (and arguably provided) > pretty much equivalent functionality in our proposal. I assume that at least > Doug, Adam, or Kris were specifically aware of Object.extend and would have > broad it up if it was relevant. One reason, it probably wasn't was that the > starting point of our design was the full reification and control of > properties and their attributes rather than just copying properties. By the > time we got around to cloning/copying issues we already had establish some > core elements of our overall design. > > Doing a bit of search I've found several different variants of the extend > function. Some are defined on Object, some on Object.prototype. Some use a > single source object and some use multiple source objects. What they all > seem to have in common is that they copy the enumerable methods from one (or > more) object to another. > > The most common use case seems to be the one where the target object is a > newly instantiated object without any properties of its own. That use case > (at least for variants of extend that only take a single source object) is > most directly supported by the Object.clone function in our proposal. > However, Object.clone is defined to be a more comprehensive object > duplication process than is performed by extend. It duplicates all own > properties and their attributes and any internal properties such as its > [[Value]] property if it has one. > > I have personally considered whether there should be some sort of mechanism > to filter the properties copied by Object.clone. For example, you might only > copy non getter/setter properties, or only enumerable properties, or perhaps > filter out ReadOnly properties. However, I never proposed any of these for > the ES3.1 spec. because I have yet to find a use case that was sufficiently > compelling or pervasive enough to justify making the interface to > Object.clone more complex (in contrast, see the explanation in the rationale > document for why we added a second argument to Object.create). If you want > to do that sort of filtering you can do it using > Object.wontbecalledgetProperty and Object.defineProperty. If you just want a > fast and comprehensive copy use Object.clone. > > The other obvious use case would seem to be adding some "mix-in" behavior to > an object (some of the descriptions of extend on the web call this > "inheritance" but it's not how I'd use that term). This use case is fairly > directly supported by Object.defineProperties although it is formulated > somewhat differently. > > As I mention in our rationale document, this design isn't just a set of > individual functions but an attempt at a unified design where we have tried > to distribute the functional elements across of set of related functions that > often have multiple uses. Object.extend is a fine function, particular when > viewed from the perspective of what can be accomplished using the available > ES3 APIs. However, it isn't something I would simply add as whole cloth to > the set of functions we have already worked out. That would mostly just > added redundant functionality and in a manner that wasn't particularly > consistent with the other functions we have defined. Instead, if we added it > we would potentially refactor the functionality of all of the proposed static > Object functions to make them stand together as a unit. I'd be happy to > discuss additional use cases to see try to see if we can find any significant > hole in our proposal. > > Finally, I want to say that my approach to a situation like this where there > appears to be multiple versions of a similar but not identical function is > not necessarily to pick one and make everybody else conform. Instead, I like > to approach the problem from the perspective of what would have made these > various functions unnecessary and what primitives would have been useful in > implementing the assorted variations. If I can provide that then future users > are unlikely to need to use the old forms and existing user can migrate by > continuing to use their old API but perhaps reimplementing them using the new > primitives. > > -----Original Message----- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Robert Sayre > Sent: Wednesday, July 16, 2008 2:17 PM > To: Mark S. Miller > Cc: es4-discuss@mozilla.org; [EMAIL PROTECTED] > Subject: Re: ES3.1 Object static methods rationale document > > Maybe someone could just give the rationale for leaving out Object.extend? > > Douglas Crockford wrote that it was considered, but I'm confused since > it looks like you haven't even seen a proposal, and didn't participate > in the discussion to exclude it. > > - Rob > > 2008/7/16 Mark S. Miller <[EMAIL PROTECTED]>: >> On Wed, Jul 16, 2008 at 10:11 AM, Brendan Eich <[EMAIL PROTECTED]> wrote: >>> And? The doc gives rationales for design decisions. What's the >>> rationale for leaving Object.extend out? >> If the document needs to give rationales for leaving out each thing we did >> not include, it would be quite a long document. What is the argument for >> adding Object.extend()? A pointer to Resig's message or a prior discussion >> is an adequate response. >> >> -- >> Cheers, >> --MarkM >> _______________________________________________ >> Es3.x-discuss mailing list >> [EMAIL PROTECTED] >> https://mail.mozilla.org/listinfo/es3.x-discuss >> > > > > -- > > Robert Sayre > > "I would have written a shorter letter, but I did not have the time." > _______________________________________________ > Es3.x-discuss mailing list > [EMAIL PROTECTED] > https://mail.mozilla.org/listinfo/es3.x-discuss > > _______________________________________________ > Es3.x-discuss mailing list > [EMAIL PROTECTED] > https://mail.mozilla.org/listinfo/es3.x-discuss > _______________________________________________ > Es3.x-discuss mailing list > [EMAIL PROTECTED] > https://mail.mozilla.org/listinfo/es3.x-discuss > -- Ingvar von Schoultz ------- (My quirky use of capitals in code comes from my opinion that reserved and predefined words should all start with lowercase, and user-defined should all start with uppercase, because this will easily and elegantly prevent a host of name-collision problems when things like programming languages are upgraded with new labels.) _______________________________________________ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss