Began work on interop chapter of manual
parent
9f401d2fec
commit
ab04f5332f
|
@ -21,7 +21,7 @@
|
||||||
##
|
##
|
||||||
|
|
||||||
info_TEXINFOS = easejs.texi
|
info_TEXINFOS = easejs.texi
|
||||||
easejs_TEXINFOS = license.texi about.texi classes.texi \
|
easejs_TEXINFOS = license.texi about.texi classes.texi interop.texi \
|
||||||
impl-details.texi integration.texi mkeywords.texi source-tree.texi
|
impl-details.texi integration.texi mkeywords.texi source-tree.texi
|
||||||
|
|
||||||
EXTRA_DIST = img README highlight.pack.js interactive.js easejs.css
|
EXTRA_DIST = img README highlight.pack.js interactive.js easejs.css
|
||||||
|
|
|
@ -55,6 +55,7 @@ Free Documentation License".
|
||||||
* Integration:: How to integrate ease.js into your project
|
* Integration:: How to integrate ease.js into your project
|
||||||
* Classes:: Learn to work with Classes
|
* Classes:: Learn to work with Classes
|
||||||
* Member Keywords:: Control member visibility and more.
|
* Member Keywords:: Control member visibility and more.
|
||||||
|
* Interoperability:: Playing nice with vanilla ECMAScript.
|
||||||
* Source Tree:: Overview of source tree
|
* Source Tree:: Overview of source tree
|
||||||
* Implementation Details:: The how and why of ease.js
|
* Implementation Details:: The how and why of ease.js
|
||||||
* License:: Document License
|
* License:: Document License
|
||||||
|
@ -69,6 +70,7 @@ Free Documentation License".
|
||||||
@include integration.texi
|
@include integration.texi
|
||||||
@include classes.texi
|
@include classes.texi
|
||||||
@include mkeywords.texi
|
@include mkeywords.texi
|
||||||
|
@include interop.texi
|
||||||
@include source-tree.texi
|
@include source-tree.texi
|
||||||
@include impl-details.texi
|
@include impl-details.texi
|
||||||
@include license.texi
|
@include license.texi
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
@c This document is part of the GNU ease.js manual.
|
||||||
|
@c Copyright (C) 2014 Free Software Foundation, Inc.
|
||||||
|
@c Permission is granted to copy, distribute and/or modify this document
|
||||||
|
@c under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||||
|
@c any later version published by the Free Software Foundation; with no
|
||||||
|
@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||||
|
@c A copy of the license is included in the section entitled ``GNU Free
|
||||||
|
@c Documentation License''.
|
||||||
|
|
||||||
|
@node Interoperability
|
||||||
|
@chapter Interoperability
|
||||||
|
GNU ease.js is not for everyone, so it is important to play nicely with
|
||||||
|
vanilla ECMAScript so that prototypes and objects can be integrated with
|
||||||
|
the strict restrictions of ease.js (imposed by classical OOP). In general,
|
||||||
|
you should not have to worry about this: everything is designed to work
|
||||||
|
fairly transparently. This chapter will go over what ease.js intentionally
|
||||||
|
supports and some interesting concepts that may even be useful even if you
|
||||||
|
have adopted ease.js for your own projects.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Using GNU ease.js Classes Outside of ease.js::
|
||||||
|
* Prototypally Extending Classes::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Using GNU ease.js Classes Outside of ease.js
|
||||||
|
@section Using GNU ease.js Classes Outside of ease.js
|
||||||
|
GNU ease.js is a prototype generator---it takes the class definition,
|
||||||
|
applies its validations and conveniences, and generates a prototype and
|
||||||
|
constructor that can be instantiated and used just as any other ECMAScript
|
||||||
|
constructor/prototype. One thing to note immediately, as mentioned in
|
||||||
|
the section @ref{Defining Classes,,Defining Classes}, is that constructors
|
||||||
|
generated by ease.js may be instantiated either with or without the
|
||||||
|
@code{new} keyword:
|
||||||
|
|
||||||
|
@float Figure, f:interop-new
|
||||||
|
@verbatim
|
||||||
|
var Foo = Class( { /*...*/ } );
|
||||||
|
|
||||||
|
// both of these are equivalent
|
||||||
|
Foo();
|
||||||
|
new Foo();
|
||||||
|
@end verbatim
|
||||||
|
@caption{Constructors generated by ease.js may omit the @code{new} keyword}
|
||||||
|
@end float
|
||||||
|
|
||||||
|
ease.js convention is to omit the keyword for more concise code that is more
|
||||||
|
easily chained, but you should follow the coding conventions of the project
|
||||||
|
that you are working on.
|
||||||
|
|
||||||
|
@node Prototypally Extending Classes
|
||||||
|
@section Prototypally Extending Classes
|
||||||
|
Since @ref{Classes,,classes} are also constructors with prototypes, they may
|
||||||
|
be used as part of a prototype chain. There are, however, some important
|
||||||
|
considerations when using any sort of constructor as part of a prototype
|
||||||
|
chain.
|
||||||
|
|
||||||
|
Conventionally, prototypes are subtyped by using a new instance as the
|
||||||
|
prototype of the subtype's constructor, as so:
|
||||||
|
|
||||||
|
@float Figure, f:interop-protochain-incorrect
|
||||||
|
@verbatim
|
||||||
|
var Foo = Class( { /*...*/ } );
|
||||||
|
|
||||||
|
// extending class as a prototype
|
||||||
|
function SubFoo() {};
|
||||||
|
SubFoo.prototype = Foo(); // INCORRECT
|
||||||
|
SubFoo.prototype.constructor = SubFoo;
|
||||||
|
@end verbatim
|
||||||
|
@caption{Incorrectly prototypally extending GNU ease.js classes}
|
||||||
|
@end float
|
||||||
|
|
||||||
|
The problem with this approach is that constructors may perform validations
|
||||||
|
on their arguments to ensure that the instance is in a consistent state. GNU
|
||||||
|
ease.js solves this problem by introducing an @code{asPrototype} method on
|
||||||
|
all classes:
|
||||||
|
|
||||||
|
@float Figure, f:interop-protochain
|
||||||
|
@verbatim
|
||||||
|
var Foo = Class( { /*...*/ } );
|
||||||
|
|
||||||
|
// extending class as a prototype
|
||||||
|
function SubFoo()
|
||||||
|
{
|
||||||
|
// it is important to call the constructor ourselves; this is a
|
||||||
|
// generic method that should work for all subtypes, even if SubFoo
|
||||||
|
// implements its own __construct method
|
||||||
|
this.constructor.prototype.__construct.apply( this, arguments );
|
||||||
|
|
||||||
|
// OR, if SubFoo does not define its own __construct method, you can
|
||||||
|
// alternatively do this:
|
||||||
|
this.__construct();
|
||||||
|
};
|
||||||
|
SubFoo.prototype = Foo.asPrototype(); // Correct
|
||||||
|
SubFoo.prototype.constructor = SubFoo;
|
||||||
|
@end verbatim
|
||||||
|
@caption{Correctly prototypally extending GNU ease.js classes}
|
||||||
|
@end float
|
||||||
|
|
||||||
|
The @code{asPrototype} method instantiates the class, but does not execute
|
||||||
|
the constructor. This allows it to be used as the prototype without any
|
||||||
|
issues, but it is important that the constructor of the subtype invokes the
|
||||||
|
constructor of the class, as in @ref{f:interop-protochain}. Otherwise, the
|
||||||
|
state of the subtype is undefined.
|
||||||
|
|
||||||
|
Keep in mind the following when using classes as part of the prototype
|
||||||
|
chain:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
GNU ease.js member validations are not enforced; you will not be warned if
|
||||||
|
an abstract method remains unimplemented or if you override a non-virtual
|
||||||
|
method, for example. Please exercise diligence.
|
||||||
|
|
||||||
|
@item
|
||||||
|
It is not wise to override non-@ref{Inheritance,,virtual} methods, because
|
||||||
|
the class designer may not have exposed a proper API for accessing and
|
||||||
|
manipulating internal state, and may not provide proper protections to
|
||||||
|
ensure consistent state after the method call.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Note the @ref{Private Member Dilemma} to ensure that your prototype works
|
||||||
|
properly in pre-ES5 environments and with potential future ease.js
|
||||||
|
optimizations for production environments: you should not define or
|
||||||
|
manipulate properties on the prototype that would conflict with private
|
||||||
|
members of the subtype. This is an awkward situation, since private
|
||||||
|
members are unlikely to be included in API documentation for a class;
|
||||||
|
ease.js normally prevents this from happening automatically.
|
||||||
|
@end itemize
|
||||||
|
|
Loading…
Reference in New Issue