Multiple Inheritance Using Classes

Is it possible to distribute only some specific part of several classes? Example:

class Walker { walk() { console.log("I am walking"); } // more functions } class Runner { run() { console.log("I am running"); } // more functions } // Make a class that inherits only the run and walk functions 
0
javascript ecmascript-6 class composition traits
Jan 29 '17 at 8:11
source share
4 answers

You can choose which methods from other classes you want to add to the existing class, as long as your new object has instance data and methods that the methods you add are expected on this object.

 class Walker { constructor() {} walk() { console.log("I am walking"); } // more functions } class Runner { constructor() {} run() { console.log("I am running"); } // more functions } class Participant { constructor() {} } // add methods from other classes to the Participant class Participant.prototype.run = Runner.prototype.run; Participant.prototype.walk = Walker.prototype.walk; 

Keep in mind that methods are simply functions that are prototype properties. That way, you can assign any functions to the prototype you want, as long as the object you put it on has the correct supporting instance data or other methods that may be needed for these newly added methods.




Of course, if we better understand your common problem, you can also solve your problem with more classical inheritance, but you cannot use inheritance to solve it exactly as you asked for it to be solved.

Standard inheritance inherits all methods of the base class. If you just need some of them, you will have to manually modify the prototype object to place only those methods that you want there.

In the future, you will get a better set of answers if you describe the problem you are trying to solve, and not the solution you are trying to implement. This allows us to understand what you are really trying to accomplish, and allows us to propose solutions that you did not even think about.

+3
Jan 29 '17 at 8:50
source share

Use composition:

 class Walker { walk() { console.log("I am walking"); } // more functions } class Runner { run() { console.log("I am running"); } // more functions } class Composite { run() { new Runner().run(); } walk() { new Walker().walk(); } } 
+2
Jan 29 '17 at 8:17
source share

Looking at the above example, I immediately suggested "... think about decomposition."

For this code, he retrieved both the walk and run behaviors. Thus, a Walker might turn out to be a hypothetical Person withWalkingAbility , a Runner , and then becomes Person withRunningAbility . All // more functions in the Walker and Runner source code can then be implemented by the Person class.

 var withSelfAwareWalkingAbility = (function mixinFactory () { // does create a closure ... function walking() { // console.log("I'm walking"); // } // return function abilityMixin () { // this.walk = walking; // shared code. // ... but shares its }; // *ability* implementation. }()), withSelfAwareRunningAbility = (function mixinFactory () { // does create a closure ... function running() { // console.log("I'm running"); // } // return function abilityMixin () { // this.run = running; // ... but shares its }; // *ability* implementation. }()); class Person { constructor() { // `Person` specific instance slots. } // `Person` specific prototypal methods. } 
The first big gain was that now it controls where to place the composition, either at the prototype level or within the constructor . It depends on the final Walker / Runner design that the OP can best answer ./

 class Walker extends Person { constructor() { super(); withSelfAwareWalkingAbility.call(this); // composition at object level / instantiation time. } } 

... against...

 class Runner extends Person { constructor() { super(); } } withSelfAwareRunningAbility.call(Runner.prototype); // composition at a `Runner` `prototype` slot. 

 var withSelfAwareWalkingAbility = (function mixinFactory () { function walking() { console.log("I'm walking"); } return function abilityMixin () { this.walk = walking; }; }()), withSelfAwareRunningAbility = (function mixinFactory () { function running() { console.log("I'm running"); } return function abilityMixin () { this.run = running; }; }()); class Person { constructor() { // `Person` specific instance slots. } // `Person` specific prototypal methods. } class Walker extends Person { constructor() { super(); withSelfAwareWalkingAbility.call(this); } } class Runner extends Person { constructor() { super(); } } withSelfAwareRunningAbility.call(Runner.prototype); var walker = (new Walker), runner = (new Runner); console.log('walker : ', walker); // Walker {walk: function} console.log('(walker instanceof Walker) ? ', (walker instanceof Walker)); // true console.log('(walker instanceof Person) ? ', (walker instanceof Person)); // true console.log('(walker instanceof Runner) ? ', (walker instanceof Runner)); // false walker.walk(); // "I'm walking" console.log('(walker.hasOwnProperty("walk")) ? ', walker.hasOwnProperty("walk")); // true console.log('\n'); console.log('runner : ', runner); // Runner {} console.log('(runner instanceof Runner) ? ', (runner instanceof Runner)); // true console.log('(runner instanceof Person) ? ', (runner instanceof Person)); // true console.log('(runner instanceof Walker) ? ', (runner instanceof Walker)); // false runner.run(); // "I'm running" console.log('(runner.hasOwnProperty("run")) ? ', runner.hasOwnProperty("run")); // false 
 .as-console-wrapper { max-height: 100%!important; top: 0; } 

Another victory in decomposing behavior into smaller or even atomic โ€œcomposite reuse unitsโ€ [^ 1] is due to the simplicity of compiling them again into larger specialized mixins / traits, such as ...

 function withSelfAwareWalkingAndRunningAbility() { withSelfAwareWalkingAbility.call(this); withSelfAwareRunningAbility.call(this); } 

[^ 1]: SCG, University of Bern: "Talents: Dynamically Compound Reuse Units"

Note ... now there is the second part of this answer , demonstrating an example from above, but with a real approach to evaluation supported by the library

0
May 2, '17 at 22:23
source share

Note ... I had to split my previous answer into two separate parts, since for a long time it was not so simple a link to external hosted javascript code. In this regard, I now provide the required feature library as a miniature inline code in the following example ...

Having the power of originally implemented talents or features in JavaScript, will make this type of composition even more flexible / powerful ...

 var withWalkingAbility = (function mixinFactory () { function walking() { return "walking"; } return function abilityMixin () { this.walk = walking; }; }()), withRunningAbility = Trait.create(function trait (use, applicator) { function running() { return "running"; } applicator(function () { this.run = running; }); }); var withSelfAwareness = (function mixinFactory () { function reflectThySelf() { return "I'm"; } return function awarenessMixin () { this.reflect = reflectThySelf; }; }()), withDepersonalization = Trait.create(function trait (use, applicator) { function objectify() { return "It's"; } applicator(function () { this.objectify = objectify; }); }); var withSelfAwareWalkingAndRunningAbility = Trait.create(function trait (use, applicator) { use(withWalkingAbility, withRunningAbility) .apply.all(); applicator(function () { this.walk = (function (proceed) { return function () { console.log([this.reflect(), proceed.call(this)].join(' ')) }; }(this.walk)); this.run = (function (proceed) { return function () { console.log([this.reflect(), proceed.call(this)].join(' ')) }; }(this.run)); }).requires([ "reflect" ]); }), withDepersonalizedRunningAbility = Trait.create(function trait (use, applicator) { use(withRunningAbility) .apply(withRunningAbility); applicator(function () { this.run = (function (proceed) { return function () { console.log([this.objectify(), proceed.call(this)].join(' ')) }; }(this.run)); }).requires([ "objectify" ]); }); class Human { constructor() { // `Human` specific instance slots. } // `Human` specific prototypal methods. } withSelfAwareness.call(Human.prototype); class Animal { constructor() { withDepersonalization.call(this); // other `Animal` specific instance slots. } // `Animal` specific prototypal methods. } class HumanWalkerAndRunner extends Human { constructor() { super(); } } withSelfAwareWalkingAndRunningAbility.call(HumanWalkerAndRunner.prototype); class AnimalRunner extends Animal { constructor() { super(); withDepersonalizedRunningAbility.call(this); } } var humanWalkerAndRunner = (new HumanWalkerAndRunner), animalRunner = (new AnimalRunner); console.log('humanWalkerAndRunner : ', humanWalkerAndRunner); // HumanWalkerAndRunner {} console.log('(humanWalkerAndRunner instanceof HumanWalkerAndRunner) ? ', (humanWalkerAndRunner instanceof HumanWalkerAndRunner)); // true console.log('(humanWalkerAndRunner instanceof Human) ? ', (humanWalkerAndRunner instanceof Human)); // true humanWalkerAndRunner.walk(); // "I'm walking" humanWalkerAndRunner.run(); // "I'm running" console.log('(humanWalkerAndRunner.hasOwnProperty("walk")) ? ', humanWalkerAndRunner.hasOwnProperty("walk")); // false console.log('(humanWalkerAndRunner.hasOwnProperty("run")) ? ', humanWalkerAndRunner.hasOwnProperty("run")); // false console.log('\n'); console.log('animalRunner : ', animalRunner); // AnimalRunner {objectify: function, run: function} console.log('(animalRunner instanceof AnimalRunner) ? ', (animalRunner instanceof AnimalRunner)); // true console.log('(animalRunner instanceof Animal) ? ', (animalRunner instanceof Animal)); // true animalRunner.run(); // "It running" console.log('(animalRunner.hasOwnProperty("run")) ? ', animalRunner.hasOwnProperty("run")); // true 
 .as-console-wrapper { max-height: 100%!important; top: 0; } 
 <script>(function(r){function g(a){var c="none",b;Y(a)&&(ta(a)?c=ua:(b=Z(a),t("^class\\s+"+a.name+"\\s+\\{").test(b)?c=va:t("\\([^)]*\\)\\s+=>\\s+\\(").test(b)?c=wa:z(a)&&(c=xa(a)?ya:za(a)||Aa(a)||Ba(a)?Ca:aa)));return c===aa}function C(a){return["^\\[object\\s+",a,"\\]$"].join("")}function v(a,c){var b=Da[c];return!!b&&0<=b.indexOf(a)}function M(a,c,b){return function(){var d=arguments;c.apply(b,d);return a.apply(b,d)}}function N(a,c,b){return function(){var d=arguments,e=a.apply(b,d);c.apply(b,d);return e}}function Ea(a,c,b,d){return function(){var e=arguments;c.call(b,e,d);return a.apply(b,e)}}function Fa(a,c,b,d){return function(){var e=arguments,f=a.apply(b,e);c.call(b,e,d);return f}}function Ga(a,c,b,d){return function(){var e=arguments,f=a.apply(b,e);c.call(b,f,e,d);return f}}function Ha(a,c,b,d){return function(){var e=arguments,f;try{f=a.apply(b,e)}catch(l){c.call(b,l,e,d)}return f}}function Ia(a,c,b,d){return function(){var e=arguments,f,g;try{f=a.apply(b,e)}catch(m){g=m}c.call(b,g||f,e,d);return f}}function Ja(a,c,b,d){return function(){return c.call(b,a,c,arguments,d)}}function Ka(a,c){return function(){var b=this[a];g(b)||(b=u);this[a]=M(b,c,this)}}function La(a,c){return function(){var b=this[a];g(b)||(b=u);this[a]=N(b,c,this)}}function Ma(a,c){return function(b){var d=this[a];g(d)||(d=u);this[a]=Ea(d,c,this,b)}}function Na(a,c){return function(b){var d=this[a];g(d)||(d=u);this[a]=Fa(d,c,this,b)}}function Oa(a,c){return function(b){var d=this[a];g(d)||(d=u);this[a]=Ga(d,c,this,b)}}function Pa(a,c){return function(b){var d=this[a];g(d)||(d=u);this[a]=Ha(d,c,this,b)}}function Qa(a,c){return function(b){var d=this[a];g(d)||(d=u);this[a]=Ia(d,c,this,b)}}function Ra(a,c){return function(b){var d=this[a];g(d)||(d=u);this[a]=Ja(d,c,this,b)}}function ba(a,c,b){a.useTraits.rules.push(new A({type:"without",traitList:c,methodNameList:b}))}function ca(a,c,b,d){a.useTraits.rules.push(new A({type:"as",trait:c,methodName:b,methodAlias:d}))}function da(a){return ea(p(a)).reduce(function(a,b){q(b)&&a.push(F(b));return a},[])}function fa(){var a,c,b,d,e;if(O(this))if(d=this.valueOf(),e=d.parentLink,w(e))if(b=e.getSetup(),a=b.chainData,c=a.recentCalleeName,v(c,"without"))if(c=da(arguments),1<=c.length)a.recentCalleeName="without",ba(b,d.traitList,c);else throw new h("Not even a single <String> type was passed to 'without' as to be excluded method name.");else{a=["\u2026 invalid chaining of '",c,"().without()'"].join("");if("applyBehavior"==c)throw new n([a," in case of excluding one or more certain behaviors."].join(""));throw new n(a);}else throw new k("Please do not spoof the context of 'use'.");else throw new k("Please do not spoof the context of 'apply'.");return e}function P(a,c){var b=a.getSetup();if(Sa(c,a.valueOf().traitList))b.chainData.recentCalleeName="applyTraits",b=new Q({traitList:c,parentLink:a}),a.putChild(b);else throw new h("Any trait that got passed to 'apply' needs to be registered before via 'use'.");return b}function Sa(a,c){return a.every(function(a){return 0<=c.indexOf(a)})}function Ta(){var a;a=this.getSetup();var c=this.valueOf().traitList;I(this,a,a.chainData.recentCalleeName);a=P(this,c);return fa.apply(a,arguments)}function Ua(){var a=this.getSetup(),c=this.valueOf().traitList;I(this,a,a.chainData.recentCalleeName);return P(this,c)}function ga(){var a,c,b;b=p(arguments);if(w(this))if(a=this.getSetup(),c=a.chainData,c=c.recentCalleeName,I(this,a,c),a=["\u2026 invalid chaining of '",c,"().apply()'"].join(""),v(c,"apply"))if(x(b[0]))if(q(b[1]))if(v(c,"applyBehavior")){c=b[0];b=F(b[1]);a=this.getSetup();var d;if(0<=this.valueOf().traitList.indexOf(c))if(d={},c.call(d),g(d[b]))a.chainData.recentCalleeName="applyBehavior",b=new R({trait:c,methodName:b,parentLink:this}),this.putChild(b);else throw new k(["The requested '",b,"' method has not been implemented by the trait that got passed to 'apply'."].join(""));else throw new h("Any trait that got passed to 'apply' needs to be registered before via 'use'.");}else throw new n([a," in case of applying just a certain behavior."].join(""));else if(p(b).every(x))if(v(c,"applyTraits"))b=P(this,b);else throw new n([a," in case of applying from one or more traits."].join(""));else throw new h("'apply(\u2026)' excepts either, as its 2nd delimiting argument, just a 'String' type or exclusively one or more 'Trait' and 'Function' types.");else throw new h("'apply(<Trait|Function>, \u2026)' excepts as its 1st argument explicitly either a 'Trait' or a 'Function' type.");else throw new n(a);else throw new k("'use(\u2026).apply(\u2026)' only works within a validly chained context, please do not try spoofing the latter.");return b}function ha(){var a;a=this;if(O(a)||G(a))a=a.valueOf(),a=a.parentLink,a=ga.apply(a,arguments);else throw new k("Please do not spoof the context of 'apply'.");return a}function I(a,c,b){var d,e;a&&!c.chainData.isTerminated&&(d=a.getChild())&&(e=d.valueOf())&&("applyTraits"==b&&O(d)?ba(c,e.traitList,[]):"applyBehavior"==b&&G(d)&&(a=e.methodName,ca(c,e.trait,a,a)));c.chainData.recentCalleeName="apply"}function R(a){this.valueOf=function(){return{trait:a.trait,methodName:a.methodName,parentLink:a.parentLink}};this.toString=function(){return["ApplyLink::singleBehavior :: ",S.stringify(a)].join("")};return this}function G(a){var c;return null!=a&&(a instanceof R||g(a.as)&&g(a.after)&&g(a.before)&&g(a.valueOf)&&(c=a.valueOf())&&x(c.trait)&&q(c.methodName)&&w(c.parentLink))}function Q(a){this.valueOf=function(){return{traitList:a.traitList,parentLink:a.parentLink}};this.toString=function(){return["ApplyLink::fromTraits :: ",S.stringify(a)].join("")};return this}function O(a){var c;return null!=a&&(a instanceof Q||g(a.without)&&g(a.valueOf)&&(c=a.valueOf())&&T(c.traitList)&&w(c.parentLink))}function U(a,c){var b=null;this.getSetup=function(){return c};this.deleteChild=function(){b=null};this.putChild=function(a){b=a};this.getChild=function(){return b};this.valueOf=function(){return{traitList:p(a.traitList)}};this.toString=function(){return["UseRoot :: ",S.stringify(a)].join("")};this.apply=ga.bind(this);this.apply.all=Ua.bind(this);this.apply.all.without=Ta.bind(this);return this}function w(a){var c;return null!=a&&(a instanceof U||g(a.apply)&&g(a.valueOf)&&g(a.getSetup)&&(c=a.valueOf())&&T(c.traitList)&&(c=a.getSetup())&&ia(c))}function Va(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(Ka(a,c));else throw new h("'before(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'before(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function Wa(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(Ma(a,c));else throw new h("'before.stateful(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'before.stateful(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function Xa(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(La(a,c));else throw new h("'after(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'after(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function Ya(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(Na(a,c));else throw new h("'after.stateful(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'after.stateful(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function Za(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(Oa(a,c));else throw new h("'afterReturning(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'afterReturning(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function $a(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(Pa(a,c));else throw new h("'afterThrowing(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'afterThrowing(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function ab(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(Qa(a,c));else throw new h("'afterFinally(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'afterFinally(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function bb(a,c){var b=this.applicator,d=b.root,e=b.modifiers;b.canRequire=!1;if(q(a))if(g(c))e.push(Ra(a,c));else throw new h("'around(\u2026, <Function>)' excepts as its 2nd argument just a 'Function' type.");else throw new h("'around(<String>, \u2026)' excepts as its 1st argument just a 'String' type.");return d}function cb(){var a=this.applicator,c=a.root,b=a.didRequire;if(a.canRequire)if(a.canRequire=!1,a.didRequire=!0,b=da(arguments),1<=b.length)a.requires=b;else throw new h("Not even a single <String> type was passed to 'requires' as method name that a trait, at its apply time, expects to be present at least.");else{if(b)throw new n("'requires' can be invoked exactly once, right after having executed a trait 'applicator' method.");throw new n("'requires' can not bee invoked after a modifier method, but has to be the direct follower of a trait 'applicator' method.");}return c}function db(a){I(this.useTraits.root,this,this.chainData.recentCalleeName);this.chainData.isTerminated=!0;var c=this.applicator,b=this.useTraits.rules,d=0>=b.length;if(!d&&!ja(b))throw new k("The trait composition language rule set does not result in applicable behavior. This happens eg if all behavior has been deleted via 'without'.");if(null!=a)if(g(a=F(a)))c.body=a,a.call(c.proxy);else throw new h("The applicator should either stay empty or receive a sole applicable type like a 'Trait' or a 'Function' type.");else d&&0>=c.modifiers.length&&D.warn("The trait descriptor till now did neither receive an applicable function via the 'applicator' method nor any composition rule via 'use(\u2026).apply(\u2026)' nor any method modifier.");return c.root}function eb(){var a;a=ea(p(arguments)).filter(function(a){return x(a)});if(1<=a.length)a=new U({traitList:a},this);else throw new h("Not even a single valid 'Trait' or 'Function' type has been provided to 'use(<Trait|Function>[, \u2026])'.");return this.useTraits.root=a}function y(a,c){return a.findIndex(function(a){return a.trait===c})}function ka(a){return{type:a.type,trait:a.trait,methodName:a.methodName}}function la(a){return{type:a.type,trait:a.trait,fromTrait:a.fromTrait,methodName:a.methodName}}function A(a){this.valueOf=function(){return fb[a.type](a)}}function ja(a){var c=!0;if(1<=a.length){var b={},c=ma(a),d=na(c);d.forEach(function(a){a.trait.call(a.proxy)});a.forEach(function(a){a.execute(b,d)});c=1<=J(b).length}return c}function gb(a,c,b){var d;if(b[0]!==oa&&(d=c.reduce(function(b,c){g(a[c])||b.push(c);return b},[]),1<=d.length))throw new h("The type misses following required method(s) \u2026 '"+d.join("', '")+"'.");return d}function hb(a,c,b){a.forEach(function(a){a.call(c,b)})}function ib(a){this.call=function(){var c=p(arguments),b;b=c.shift();b=null!=b&&b||null;a.apply(b,c);return b};this.apply=function(c,b){null==b&&(b=[]);c=null!=c&&c||null;a.apply(c,b);return c};return this}function jb(a){this.requires=function(){return p(a)};return this}function kb(a){var c=[],b={};a.call(b,oa);c=J(b).sort(function(a,b){return a<b&&-1||a>b&&1||0});b=null;this.keys=function(){return p(c)};return this}function pa(a,c){this.toString=function(){return"[object Trait]"};this.valueOf=function(){return a};ib.call(this,a);jb.call(this,c);kb.call(this,a);return this}function qa(a){var c;if(c=!!a)(c=a instanceof pa)||(c="object"==typeof a&&g(a.call)&&g(a.apply)&&g(a.valueOf)&&g(a.valueOf()));return c}function x(a){return qa(a)||g(a)}function ma(a){return a.reduce(function(a,b){var c=b.valueOf(),e=c.trait,f=c.fromTrait;e&&0>a.indexOf(e)&&a.push(e);f&&0>a.indexOf(f)&&a.push(f);(c.traitList||[]).forEach(function(b){0>a.indexOf(b)&&a.push(b)});return a},[])}function na(a){return a.map(function(a){return{trait:a,proxy:{}}})}function lb(a,c,b,d){var e=[],f={};if(!(0>=c.length||ja(c)))throw new k("The trait composition language rule set does not result in applicable behavior. This happens eg if all behavior has been deleted via 'without'.");g(b)&&(b.call(f),e=J(f));return[a,c,e,d].some(function(a){return 1<=a.length})}function mb(a){var c,b=a.useTraits.rules,d=a.applicator;a=d.body;var e=d.requires,d=d.modifiers,f=ma(b);lb(f,b,a,d)&&(d=function(a,b,c,d,e){return function(){var f=this,h=p(arguments),l=na(a);l.forEach(function(a){a.trait.apply(a.proxy,h)});b.forEach(function(a){a.execute(f,l)});gb(f,c,h);g(d)&&d.apply(f,h);hb(e,f,h);return f}}(f,b,e,a,d),c=new pa(d,e));return c}var V=r.Function,H=r.Object,B=r.Array,t=r.RegExp,S=r.JSON,h=r.TypeError,k=r.ReferenceError,n=r.SyntaxError,nb=V.prototype,K=H.prototype,ra=U.prototype,sa=Q.prototype,L=R.prototype,oa={},aa="applicable-function",ya="buildin-constructor",va="class-constructor",wa="arrow-function",ua="generator-function",Ca="interface-type",Da={without:["apply","applyTraits"],as:["apply","applyBehavior"],after:["apply","applyBehavior","after","before"],before:["apply","applyBehavior","after","before"],apply:"apply applyBehavior applyTraits without as after before use".split(" "),applyTraits:"apply applyBehavior applyTraits without as after before use".split(" "),applyBehavior:"apply applyBehavior applyTraits without as after before use".split(" ")},fb={beforeWrap:ka,afterWrap:ka,beforeApply:la,afterApply:la,without:function(a){return{type:a.type,traitList:p(a.traitList),methodNameList:p(a.methodNameList)}},as:function(a){return{type:a.type,trait:a.trait,methodName:a.methodName,methodAlias:a.methodAlias}}},ob={beforeWrap:function(a,c,b){var d=y(b,a.trait);b=b[d];a=a.methodName;c[a]=M((b&&b.proxy||{})[a],c[a],c)},afterWrap:function(a,c,b){var d=y(b,a.trait);b=b[d];a=a.methodName;c[a]=N((b&&b.proxy||{})[a],c[a],c)},beforeApply:function(a,c,b){var d=y(b,a.trait),e=y(b,a.fromTrait),d=b[d],e=b[e];b=d&&d.proxy||{};e=e&&e.proxy||{};a=a.methodName;a in c&&delete c.methodName;c[a]=M(b[a],e[a],c)},afterApply:function(a,c,b){var d=y(b,a.trait),e=y(b,a.fromTrait),d=b[d],e=b[e];b=d&&d.proxy||{};e=e&&e.proxy||{};a=a.methodName;a in c&&delete c.methodName;c[a]=N(b[a],e[a],c)},without:function(a,c,b){var d=a.traitList,e=a.methodNameList.reduce(function(a,b){a[b]=null;return a},{});d.forEach(function(a){a=y(b,a);var d=(a=b[a])&&a.proxy||{};J(d).forEach(function(a){a in e||(a in c&&delete c.methodName,c[a]=function(a,b){return function(){return a.apply(b,arguments)}}(d[a],c))})});a=b=d=e=null},as:function(a,c,b){var d=y(b,a.trait);b=(b=b[d])&&b.proxy||{};d=a.methodAlias;a=a.methodName;d in c&&delete c.methodAlias;c[d]=function(a,b){return function(){return a.apply(b,arguments)}}(b[a],c);a=b=d=b=b=d=a=null}},F=function(a,c){return function(b){return b==c?b:a.call(b).valueOf()}}(K.valueOf,null),E=function(a){return function(c){return a.call(c)}}(K.toString),Z=function(a){return function(c){return a.call(c)}}(nb.toString),pb=function(a){try{a.call(null,"length"),a=function(a,b){return function(c,e){return c!=b&&a.call(c,e)}}(a,null)}catch(c){a=function(a,c){return function(b,d){var e=b!=c;if(e)try{e=a.call(b,d)}catch(m){e=!0}return e}}(a,null)}return a}(K.propertyIsEnumerable),Y=function(a){return function(c){return typeof c==a}}(typeof V),z=function(a){return function(c){return Y(c)&&typeof c.call==a&&typeof c.apply==a}}(typeof V),qb=function(a){return function(c){return t(a).test(E(c))}}(C("Function")),ia=function(a){return function(c){return t(a).test(E(c))}}(C("Object")),rb=z(H.getPrototypeOf)&&H.getPrototypeOf||function(a){var c=a&&a.__proto__;return c||null===c?c:qb(a.constructor)?a.constructor.prototype:a instanceof H?K:null},W=function(a){return function(c){return(c=t(a).exec(Z(c)))&&c[1]}}("^function\\s+([^(]+)\\("),xa=function(a){return function(c){return t(a).test(W(c))}}("^(?:Array|ArrayBuffer|AsyncFunction|Atomics|Boolean|DataView|Date|Error|EvalError|Float32Array|Float64Array|Function|Generator|GeneratorFunction|Int16Array|Int32Array|Int8Array|InternalError|Collator|DateTimeFormat|NumberFormat|Iterator|Map|Number|Object|Promise|Proxy|RangeError|ReferenceError|RegExp|Bool16x8|Bool32x4|Bool64x2|Bool8x16|Float32x4|Float64x2|Int16x8|Int32x4|Int8x16|Uint16x8|Uint32x4|Uint8x16|Set|SharedArrayBuffer|StopIteration|String|Symbol|SyntaxError|TypeError|TypedArray|URIError|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|WeakMap|WeakSet)$"),X=function(a,c){var b=t(c);return b.test(W(a))||b.test(W(rb(a)))},za=function(a){return function(c){return X(c,a)}}("^(?:Node|CharacterData|Event|DOMError|DOMException|DOMImplementation|DOMStringList|DOMTokenList|EventTarget|HTMLCollection|MutationObserver|MutationRecord|NodeFilter|NodeIterator|NodeList|Range|TreeWalker|URL|Document)$"),Aa=function(a){return function(c){return X(c,a)}}("^(?:HTMLElement|HTMLMediaElement|Element)$"),Ba=function(a){return function(c){return X(c,a)}}("^(?:CanvasRenderingContext2D|CanvasGradient|CanvasPattern|TextMetrics|ImageData|DOMStringMap|MediaError|HTMLCollection|NodeList)$"),ta=function(a){return function(c){return t(a).test(E(c))}}(C("GeneratorFunction")),q=function(a){return function(c){return t(a).test(E(c))}}(C("String")),T=z(B.isArray)&&B.isArray||function(a){return function(c){return t(a).test(E(c))}}(C("Array")),sb=z(B.isArguments)&&B.isArguments||function(a,c){var b=function(b){return t(a).test(E(b))};b(arguments)||(b=function(a){return ia(a)&&"number"==typeof a.length&&c(a.length)&&!pb(a,"length")});return b}(C("Arguments"),r.Number.isFinite),p=z(B.from)&&B.from||function(a){return function(c){return a.call(c)}}(B.prototype.slice),ea=function c(b){b=sb(b)&&p(b)||b;T(b)&&(b=b.reduce(function(b,e){return b.concat(c(e))},[]));return b},J=H.keys,u=function(){},D;D=(D=r.console)&&z(D.warn)&&z(D.log)&&D||{warn:u,log:u};L.as=function(c){var b,d,e,f,g;if(G(this))if(f=this.valueOf(),g=f.parentLink,w(g))if(e=g.getSetup(),d=e.chainData,b=d.recentCalleeName,v(b,"as"))if(q(c=F(c)))if(b=f.trait,f=f.methodName,f!==c)d.recentCalleeName="as",ca(e,b,f,c);else throw new h("Using identical method names in case of aliasing is considered to be a rule violating contradiction.");else throw new h("'as(<String>)' excepts as its sole argument just a 'String' type.");else{c=["\u2026 invalid chaining of '",b,"().as()'"].join("");if("applyTraits"==b)throw new n([c," in case of aliasing just a certain behavior."].join(""));throw new n(c);}else throw new k("Please do not spoof the context of 'use'.");else throw new k("Please do not spoof the context of 'apply'.");return g};L.after=function(c){var b,d,e,f,l,m;if(G(this))if(f=this.valueOf(),m=f.parentLink,w(m))if(e=m.getSetup(),d=e.chainData,b=d.recentCalleeName,v(b,"after"))if(x(c))if(b=m.valueOf(),b=b.traitList,0<=b.indexOf(c))if(b=f.trait,b!==c)if(l=f.methodName,f={},c.call(f),g(f[l]))d.recentCalleeName="after",e.useTraits.rules.push(new A({type:"afterApply",trait:c,fromTrait:b,methodName:l}));else throw new k(["Please consider applying '",l,"' directly. This expected behavior has not been implemented by the trait that got passed to 'after'."].join(""));else throw new k("Passing identical trait references to both 'apply' and 'after' is a contradiction that violates the composition rules.");else throw new h("Any trait passed to 'after' has to be registered before via 'use'.");else throw new h("'after(<Trait|Function>)' excepts as its sole argument explicitly either a 'Trait' or a 'Function' type.");else throw new n(["\u2026 invalid chaining of '",b,"().after()'"].join(""));else throw new k("Please do not spoof the context of 'use'.");else throw new k("Please do not spoof the context of 'apply'.");return m};L.before=function(c){var b,d,e,f,l,m;if(G(this))if(f=this.valueOf(),m=f.parentLink,w(m))if(e=m.getSetup(),d=e.chainData,b=d.recentCalleeName,v(b,"before"))if(x(c))if(b=m.valueOf(),b=b.traitList,0<=b.indexOf(c))if(b=f.trait,b!==c)if(l=f.methodName,f={},c.call(f),g(f[l]))d.recentCalleeName="before",e.useTraits.rules.push(new A({type:"beforeApply",trait:c,fromTrait:b,methodName:l}));else throw new k(["Please consider applying '",l,"' directly. This expected behavior has not been implemented by the trait that got passed to 'before'."].join(""));else throw new k("Passing identical trait references to both 'apply' and 'before' is a contradiction that violates the composition rules.");else throw new h("Any trait passed to 'before' has to be registered before via 'use'.");else throw new h("'before(<Trait|Function>)' excepts as its sole argument explicitly either a 'Trait' or a 'Function' type.");else throw new n(["\u2026 invalid chaining of '",b,"().before()'"].join(""));else throw new k("Please do not spoof the context of 'use'.");else throw new k("Please do not spoof the context of 'apply'.");return m};L.apply=ha;sa.without=fa;sa.apply=ha;ra.after=function(c){var b,d,e,f;if(w(this))if(e=this.getSetup(),d=e.chainData,b=d.recentCalleeName,v(b,"after"))if(x(c))if(b=this.valueOf(),b=b.traitList,0<=b.indexOf(c))if(b=this.getChild(),f=b.valueOf(),b=f.trait,b!==c)if(f=f.methodName,b={},c.call(b),g(b[f]))d.recentCalleeName="after",e.useTraits.rules.push(new A({type:"afterWrap",trait:c,methodName:f}));else throw new k(["Please consider applying '",f,"' directly. This expected behavior has not been implemented by the trait that got passed to 'after'."].join(""));else throw new k("Passing identical trait references to both 'apply' and 'after' is a contradiction that violates the composition rules.");else throw new h("Any trait passed to 'after' has to be registered before via 'use'.");else throw new h("'after(<Trait|Function>)' excepts as its sole argument explicitly either a 'Trait' or a 'Function' type.");else throw new n(["\u2026 invalid chaining of '",b,"().after()'"].join(""));else throw new k("Please do not spoof the context of 'use'.");return this};ra.before=function(c){var b,d,e,f;if(w(this))if(e=this.getSetup(),d=e.chainData,b=d.recentCalleeName,v(b,"before"))if(x(c))if(b=this.valueOf(),b=b.traitList,0<=b.indexOf(c))if(b=this.getChild(),f=b.valueOf(),b=f.trait,b!==c)if(f=f.methodName,b={},c.call(b),g(b[f]))d.recentCalleeName="before",e.useTraits.rules.push(new A({type:"beforeWrap",trait:c,methodName:f}));else throw new k(["Please consider applying '",f,"' directly. This expected behavior has not been implemented by the trait that got passed to 'before'."].join(""));else throw new k("Passing identical trait references to both 'apply' and 'before' is a contradiction that violates the composition rules.");else throw new h("Any trait passed to 'before' has to be registered before via 'use'.");else throw new h("'before(<Trait|Function>)' excepts as its sole argument explicitly either a 'Trait' or a 'Function' type.");else throw new n(["\u2026 invalid chaining of '",b,"().before()'"].join(""));else throw new k("Please do not spoof the context of 'use'.");return this};A.prototype.execute=function(c,b){var d=this.valueOf();ob[d.type](d,c,b)};return r.Trait={create:function(c){var b,d,e;g(c=F(c))&&(e={chainData:{isTerminated:!1,recentCalleeName:"use"},useTraits:{root:null,rules:[]},applicator:{body:null,proxy:{},root:{},modifiers:[],requires:[],canRequire:!0,didRequire:!1}},b=e.applicator.root,b.requires=cb.bind(e),b.before=Va.bind(e),b.after=Xa.bind(e),b.before.stateful=Wa.bind(e),b.after.stateful=Ya.bind(e),b.afterReturning=Za.bind(e),b.afterThrowing=$a.bind(e),b.afterFinally=ab.bind(e),b.around=bb.bind(e),b=eb.bind(e),d=db.bind(e),c(b,d),e=mb(e));return e},isTrait:qa,isApplicable:x}})(Function("return this")());</script> 
0
Aug 29 '17 at 12:54 on
source share



All Articles