Object.mixin() reacher proposal

Andrea Giammarchi andrea.giammarchi at gmail.com
Sun Apr 14 14:48:04 PDT 2013


somebody already raised the concern "what if I want to mixin the function
as object, not as callable"

I think being [[Call]] not possible to mixin as object functionality, and
being functions all by default having ownProperties such ["arguments",
"name", "length", "caller"] .. that would simply clash so function as
argument, for this purpose, is never ambiguous, but of course a function
could be the target object, if needed

var withMoar = Object.mixin(function(){}, mixinFunction);
// same as mixinFunction.call(function(){});







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

> yeah that's better - I was having a senior moment - most constructor
> functions will normally reside in the prototype of course
>
>
> On Sun, Apr 14, 2013 at 1:59 PM, Andrea Giammarchi <
> andrea.giammarchi at gmail.com> wrote:
>
>> 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/37dddc18/attachment-0001.html>


More information about the es-discuss mailing list