Object.mixin() reacher proposal

Andrea Giammarchi andrea.giammarchi at gmail.com
Sun Apr 14 10:07:34 PDT 2013


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'));
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130414/203aeae4/attachment-0001.html>


More information about the es-discuss mailing list