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

Reply via email to