Previous: Method Wrapping, Up: Visibility Implementation


B.2.5 Pre-ES5 Fallback

For any system that is to remain functionally compatible across a number of environments, one must develop around the one with the least set of features. In the case of ease.js, this means designing around the fact that it must maintain support for older, often unsupported, environments.1 The line is drawn between ECMAScript 5 and its predecessors.

As mentioned when describing the proxy implementation (see Property Proxies), ease.js's ability to create a framework that is unobtrusive and fairly easy to work with is attributed to features introduced in ECMAScript 5, primarily getters and setters. Without them, we cannot proxy between the different visibility layers (see Visibility Object Implementation). As a consequence, we cannot use visibility layers within a pre-ES5 environment.

This brings about the subject of graceful feature degradation. How do we fall back while still allowing ease.js to operate the same in both environments?

B.2.5.1 Visibility Fallback

Visibility fallback is handled fairly simply in ease.js polymorphically with the FallbackVisibilityObjectFactory prototype (as opposed to VisibilityObjectFactory which is used in ES5+ environments), which does the following:

Classical Object-Oriented programming has many rich features, but many of its “features” are simply restrictions it places on developers. This simple fact works to our benefit. However, in this case of a visibility implementation, we aren't dealing only with restrictions. There is one exception.

Unfortunately, this necessary fallback introduces a startling limitation: Consider what might happen if a subtype defines a private member with the same name as the supertype. Generally, this is not an issue. Subtypes have no knowledge of supertypes' private members, so there is no potential for conflict. Indeed, this is the case with our visibility implementation (see Visibility Object Implementation. Unfortunately, if we merge all those layers into one, we introduce a potential for conflict.

B.2.5.2 Private Member Dilemma

With public and protected members (see Access Modifiers), we don't have to worry about conflicts because they are inherited by subtypes (see Inheritance). Private members are intended to remain distinct from any supertypes; only that specific class has access to its own private members. As such, inheritance cannot be permitted. However, by placing all values in the prototype chain (the public layer), we are permitting inheritance of every member. Under this circumstance, if a subtype were to define a member of the same name as a supertype, it would effectively be altering the value of its supertype. Furthermore, the supertype would have access to the same member, allowing it to modify the values of its subtypes, which does not make sense at all!

This means that we have to place a certain restriction on ease.js as a whole; we must prevent private member name conflicts even though they cannot occur in ES5 environments. This is unfortunate, but necessary in order to ensure feature compatibility across the board. This also has the consequence of allowing the system to fall back purely for performance benefits (no overhead of the visibility object).

B.2.5.3 Forefitting Fallbacks

Although ease.js allows flexibility in what environment one develops for, a developer may choose to support only ES5+ environments and make use of ES5 features. At this point, the developer may grow frustrated with ease.js limiting its implementation for pre-ES5 environments when their code will not even run in a pre-ES5 environment.

For this reason, ease.js may include a feature in the future to disable these limitations on a class-by-class2 basis in order to provide additional syntax benefits, such as omission of the static access modifiers (see Static Implementation) and removal of the private member conflict check.


Footnotes

[1] ease.js was originally developed for use in software that would have to maintain compatibility as far back as IE6, while still operating on modern web browsers and within a server-side environment.

[2] Will also include traits in the future.