On 06.08.2014 06:38, Rick Waldron wrote:
On Tuesday, August 5, 2014, Domenic Denicola
<dome...@domenicdenicola.com <mailto:dome...@domenicdenicola.com>> wrote:
I sympathize; I have always found the fact that bare `super()`
works to be confusing.
When a bare super() call appears in a method (whether constructor or
not) it can only have _one_ _meaning_ and that's a call to a method of
the same name in the parent class. This isn't particularly innovative:
John Resig's Simple JavaScript Inheritance[0]—arguably one of the most
widely used (many clones, forks and spin-offs exist) "abstract class"
techniques—provides `this._super()` which does the same thing that ES6
super() does. This pattern existed before and has been repeated
throughout many libraries that have stood out over the years:
Prototype, Dojo, Ext.js and certainly others. CoffeeScript implements
super() this way as well.
Rick
[0] http://ejohn.org/blog/simple-javascript-inheritance/
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
I wonder why you chose that way in the spec. An issue I can see here is
that mixin-based inheritance on a per-method basis won't work properly
as expected.
In my game engine lycheeJS, I'm using a mixin based inheritance to allow
a) inclusions based on feature detection (html, nodejs, v8gl, etc.)
b) inclusions in a specified order (a la a extends b extends c)
c) overwrites of your method with super calls to both via direct
b.prototype (or c.prototype) access
d) mixin based includes that allow inclusions _of single methods_ of
other classes
Simplified Example:
var a = function(settings) {
// moar stuff
b.call(this,settings);
c.call(this,settings);
};
a.prototype = { render: function() {
c.prototype.render.call(this);
doCustomStuffInBetween();
b.prototype.render.call(this);
}};
The last reasons (c, d) are very important to my game engine, because it
allows inclusion of single "public" methods. For example, you can reuse
a 2D render() method of a ui.State for rendering the UI layer, then draw
something in 3D on top of it via the game.State.
To access those namespaces properly, I have to create all definitions
inside a closure with "dynamic" arguments. For example:
lychee.define('lychee.Renderer').exports(function(lychee, global,
attachments) {});
lychee.define('game.Renderer').exports(function(lychee, game, global,
attachments) {});
That allows me some essential things for the engine concept:
a) every definition can be exported in a sandbox
b) theoretically sandboxes of supports() (feature detection callbacks)
are possible with new Proxies, currently they have to be executed global
(different story of detecting type-based access to properties that are
not existing at runtime and need to be dispatched)
c) every definition can be serialized as a string and deserialized
later, in sandboxed state without requiring access to global properties
d) global accesses to properties or bound variables from outer scopes
are easily traceable via try/catch
e) global can be faked, it is not existing and not "window", it's a
reference to lychee.Environment's global property.
An example of this mixin-based inheritance usage can be found here:
https://github.com/LazerUnicorns/lycheeJS/blob/development-0.8/projects/boilerplate/source/entity/Circle.js#L99
PS: If you are curious, install lycheeJS via README.md and run the
localhost:8080/projects/boilerplate. Then call
lychee.environment.serialize(); which creates the JSON that is
deserializable (and injectable) at runtime.
Also, what is *REALLY* important (I can't stress that enough).
JavaScript has a huge bonus when being compared to other programming
languages. Namespaces are just objects in global scope that can exist at
runtime, not necessarily at compile time or definition time. Access to
lychee.game.Main is just new
lychee.Environment().global.lychee.game.Main. The advantage here is that
global can be faked as a sandbox and can be isolated to trace errors
occuring on a per-definition base at runtime. (Namely remote debugging
and remote code injection via websockets)
This leads to the possibility of inclusion of different libraries under
a _different namespace_. All libraries think they have say the "game"
namespace, but in fact, you can include them in a different project
under a custom namespace. Every library, if sandboxed, will never
pollute the "global namespace".
These features were the killer decision for me to use JavaScript as a
game engine base, otherwise I probably would've used Lua (I'm honest).
I would recommend having those listed features in mind when talking
about super() and namespaces, because the current spec still will
prevent me from using native "class" keyword in JavaScript.
If newbies ask me if they should use classes, I say no to them, because
I still think the featureset of a mixin-based inheritance (leading to
fancy prototype copying and sealing) is still better.
Cheers,
~Christoph
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss