Search code examples
javascriptmootools

Why must Extends be the first property in a mootools class definition?


The mootools docs state that "The Extends property should be the first property in a class definition.". After hours of investigation I stumbled upon this line in the mootools doc.

Although my original problem could be solved after settings Extends as the first property I do not understand why.

According to the js docs the order of properties in an object is subject of engine implementation. No guarantee of any kind is made about the order.

So why does mootools rely on the order? Trying to read the mootools code did not help me ;).


Solution

  • First of all, understand this: the MooTools Class constructor takes the simple object that you pass to it and then loops through the properties

    Let's start with implement - https://github.com/mootools/mootools-core/blob/master/Source/Class/Class.js#L75 - is being called against all properties passed to the Class constructor. It is an overloaded function - see https://github.com/mootools/mootools-core/blob/master/Source/Class/Class.js#L98 - which allows it to work with an object of key -> value pairs. the overloadSetter uses standard for (var key in obj) loop, which in most implementations will be FIFO - disregarding webkit's weird tendency to sort keys and return those that have numeric indexes or start with numeric chars first. ECMA spec does not guarantee order of properties

    When looping through object properties, it will try to look through the mutators defined under Class.Mutators - Extends and Implements - https://github.com/mootools/mootools-core/blob/master/Source/Class/Class.js#L100-L113

    In the case of extends, it will set the parent property and also set the prototype of your new object constructor - https://github.com/mootools/mootools-core/blob/master/Source/Class/Class.js#L103-L104 - and this needs to happen early on. It does not specifically pluck Extends/Implements because it was built to be extendible and to allow you to add your own custom Mutators, eg. Binds in MooTools-more - perhaps not the only solution, but some things are better left as awkward yet flexible API, as opposed to rigid and non-DRY sugar

    Particularly, things will break when Implements is before Extends as Implements will actually ... nevermind - I have described that in a blog post a very long time ago when I first encountered it - but spoke to a few MooTools core devs and it became clear why. See what I had to go through here: http://fragged.org/mootools-pattern-fun-class-implements-extends-at-the-same-time_1359.html

    Arguably, things were better in the now defunct mootools-2.0 AMD branch here- https://github.com/kamicane/mootools-core/blob/define-2/Source/Core/Class.js#L19

    So - for now, we need to live with it - until Prime is out anyway.