Object.mixin() reacher proposal

Andrea Giammarchi andrea.giammarchi at gmail.com
Sun Apr 14 13:59:43 PDT 2013


My previous version was doing that in a probably too smart way so I've
simplified the proposal simply accepting, in that example

Object.mixin(Thung.prototype, Thing.proottype);
Object.mixin(Thung.prototype, Thang.proottype);

It does not look so black magic anymore but it's way less ambiguous than
the first proposal (I guess)

Thanks




On Sun, Apr 14, 2013 at 1:34 PM, Angus Croll <anguscroll at gmail.com> wrote:

> Lending my support to Object.mixin accepting a function as the
> argument—but no surprise there I guess :)
>
> Note: since functional mixins and constructors are syntactically identical
> we can now get gorgeously expressive—and make type inheritance way simpler
> (for the first time allowing multiple type inheritance)
>
> //make a new thing and a new thang
> var thing = new Thing;
> var thang = new Thang;
>
> //OR have Thung inherit from Thing and Thang
> Object.mixin(Thung.prototype, Thing);
> Object.mixin(Thung.prototype, Thang);
>
>
> On Sun, Apr 14, 2013 at 12:59 PM, Andrea Giammarchi <
> andrea.giammarchi at gmail.com> wrote:
>
>> right, I've simplified a lot and tested cross platform:
>>
>> https://github.com/WebReflection/object-mixin#object-mixin
>>
>> thoughts?
>>
>>
>> On Sun, Apr 14, 2013 at 10:07 AM, Andrea Giammarchi <
>> andrea.giammarchi at gmail.com> wrote:
>>
>>> OK, maybe just code was a non-sense ...
>>>
>>> So, the idea behind is mark a function explicitly as mixin ... how ?
>>>
>>> Any function that is passed and has an empty prototype (then is user
>>> defined or native) could be considered invocable as mixin.
>>>
>>> function addFunctionality() {
>>>   this.method = function () {
>>>     // now the outer context has a method
>>>   };
>>> }
>>>
>>> // mark the prototype as empty in ES5
>>> delete addFunctionality.prototype.constructor;
>>>
>>> function MyClass() {}
>>>
>>> Object.mixin(MyClass.prototype, addFunctionality);
>>>
>>> rather than only
>>>
>>> Object.mixin(MyClass.prototype, {method: function () {}});
>>>
>>> If the prototype has at least one own property in its prototype it will
>>> be considered a constructor so that:
>>>
>>> Object.mixin(MyClass.prototype, MySuperClass);
>>>
>>> can easily be transformed implicitly into:
>>> Object.mixin(MyClass.prototype, MySuperClass.prototype);
>>>
>>>
>>> This case is, however, less important, the fact Object.mixin should be
>>> able to accept a function and invoke it with target as context with
>>> optional arguments would be really a **great idea**, IMHO
>>>
>>> Thanks
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Sun, Apr 14, 2013 at 2:45 AM, Andrea Giammarchi <
>>> andrea.giammarchi at gmail.com> wrote:
>>>
>>>> also, in case you are guessing the typo .. reacher because it could
>>>> reach more (older) engines, doing a joke with richer .... got it? .. too
>>>> damn fun, I know!
>>>>
>>>>
>>>> On Sun, Apr 14, 2013 at 2:04 AM, Andrea Giammarchi <
>>>> andrea.giammarchi at gmail.com> wrote:
>>>>
>>>>> apologies
>>>>> getOwnPropertyDescriptor(
>>>>>     source,
>>>>>     key
>>>>> )
>>>>>
>>>>> should have been
>>>>> getOwnPropertyDescriptor(
>>>>>     enricher,
>>>>>     key
>>>>> )
>>>>>
>>>>>
>>>>> On Sun, Apr 14, 2013 at 1:58 AM, Andrea Giammarchi <
>>>>> andrea.giammarchi at gmail.com> wrote:
>>>>>
>>>>>> what I've written here:
>>>>>>
>>>>>> https://github.com/WebReflection/object-mixin/blob/master/src/object-mixin.js
>>>>>>
>>>>>> is a better proposal for the potential `Object.mixin()` in current
>>>>>> ES6 specs.
>>>>>>
>>>>>> It seems that Mixins Are Awesome and this can take most advantages
>>>>>> from being a function and not only an object:
>>>>>>
>>>>>> http://webreflection.blogspot.ie/2013/04/flight-mixins-are-awesome.html
>>>>>>
>>>>>> AFAIK, all interfaces described in W3C such EventTarget and others
>>>>>> could be also covered by this proposal ... so ... what do you think ?
>>>>>>
>>>>>> /*jslint browser: true, forin: true, plusplus: true, indent: 4 */
>>>>>> (function(Object, mixin) {
>>>>>>     "use strict"; // happy linter ^_____^
>>>>>>
>>>>>>     /* <droppable>
>>>>>>      * adhoc polyfill section for this purpose only
>>>>>>      * never use these functions outside this closure ... like ...
>>>>>> ne*/var
>>>>>>     /*
>>>>>> ^ ... you see that? only reason I chose 4 spaces indentations here :D
>>>>>>       also this comment ... pure quality, right ?!?! ... anyway ... */
>>>>>>
>>>>>>         // for IE < 9 Desktop browsers
>>>>>>         defineProperty = Object.defineProperty ||
>>>>>>         function (o, k, d) {
>>>>>>             o[k] = d.value;
>>>>>>         },
>>>>>>         // same as above
>>>>>>         getOwnPropertyNames = Object.getOwnPropertyNames ||
>>>>>>         function (o) {
>>>>>>             var
>>>>>>                 // in case the guy does not inherit from
>>>>>> Object.prototype
>>>>>>                 has = Object.prototype.hasOwnProperty,
>>>>>>                 result = [],
>>>>>>                 key;
>>>>>>             for (key in o) {
>>>>>>                 // in non ES5 compliant browsers
>>>>>>                 // there's no way to define properties
>>>>>>                 // as non enumerable unless these are
>>>>>>                 // there by default, like "constructor" is
>>>>>>                 // for functions.prototype
>>>>>>                 if (has.call(o, key)) {
>>>>>>                     result.push(key);
>>>>>>                 }
>>>>>>             }
>>>>>>             return result;
>>>>>>         },
>>>>>>         // again ... IE < 8
>>>>>>         getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor ||
>>>>>>         function (o, k) {
>>>>>>             return {
>>>>>>                 enumerable: true,
>>>>>>                 writable: true,
>>>>>>                 configurable: true,
>>>>>>                 value: o[k]
>>>>>>             };
>>>>>>         };
>>>>>>     // </droppable>
>>>>>>
>>>>>>     // if already defined get out of here
>>>>>>     // this should be
>>>>>>     // if (mixin in Object) return;
>>>>>>     // but for some reason I went for JSLint ...
>>>>>>     if (Object[mixin]) {
>>>>>>         return;
>>>>>>     }
>>>>>>     // same descriptor as other spec'd methods
>>>>>>     defineProperty(
>>>>>>         Object,
>>>>>>         mixin,
>>>>>>         {
>>>>>>             enumerable: false,
>>>>>>             writable: true,
>>>>>>             configurable: true,
>>>>>>             value: function mixin(
>>>>>>                 target, // object to enrich with
>>>>>>                 source    // mixin object/function
>>>>>>             ) {
>>>>>>                 var
>>>>>>                     // check if source is a function
>>>>>>                     enricher = typeof source === 'function' ?
>>>>>> source.prototype : source,
>>>>>>                     // per each own property name
>>>>>>                     keys = getOwnPropertyNames(enricher),
>>>>>>                     length = keys.length,
>>>>>>                     i = 0,
>>>>>>                     key;
>>>>>>                 while (i < length) {
>>>>>>                     // define it ...
>>>>>>                     defineProperty(
>>>>>>                         target,
>>>>>>                         key = keys[i++],
>>>>>>                         // ... via same property descriptor
>>>>>>                         getOwnPropertyDescriptor(
>>>>>>                             source,
>>>>>>                             key
>>>>>>                         )
>>>>>>                     );
>>>>>>                 }
>>>>>>                 // if the object had no own names
>>>>>>                 // it's quite clear the intention of the user
>>>>>>                 // so that if a function without properties
>>>>>>                 // is passed through this method ...
>>>>>>                 if (!length && typeof source === 'function') {
>>>>>>                     // this function is invoked with the target
>>>>>>                     // as its own context
>>>>>>                     source.apply(
>>>>>>                         target,
>>>>>>                         // optional arguments to initialize defaults
>>>>>>                         // for this mixin might be accepted too
>>>>>>                         keys.slice.call(arguments, 2)
>>>>>>                     );
>>>>>>                 }
>>>>>>                 // always return the initial target
>>>>>>                 // ignoring a possible different return
>>>>>>                 // in latter case: consistency with this method
>>>>>>                 return target;
>>>>>>             }
>>>>>>         }
>>>>>>     );
>>>>>> }(Object, 'mixin'));
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130414/c10217c6/attachment-0001.html>


More information about the es-discuss mailing list