1
0
Fork 0

Modernize documentation examples

Despite working with ES3+, the perceived age of the project is probably a
deterrent, and we really should be showing users the modern way of doing
things.

`impl-details.texi' was _not_ modernized because those details are indeed
specific to ES3.

* doc/classes.texi:
* doc/integration.texi:
* doc/interop.texi:
* doc/mkeywords.texi: Update documentation.
master
Mike Gerwitz 2017-11-02 00:52:00 -04:00
parent bb3956f1b4
commit 5c3b7ab042
Signed by: mikegerwitz
GPG Key ID: 8C917B7F5DC51BA2
4 changed files with 172 additions and 181 deletions

View File

@ -35,7 +35,7 @@ object in JavaScript:
*/
// our "class"
var MyClass = function()
const MyClass = function()
{
this.prop = 'foobar';
}
@ -47,7 +47,7 @@ object in JavaScript:
};
// create a new instance of the class and execute doStuff()
var foo = new MyClass();
const foo = new MyClass();
console.log( foo.getProp() ); // outputs "foobar"
@end verbatim
@caption{Basic ``Class'' in JavaScript @emph{without} using ease.js}
@ -202,20 +202,21 @@ Let's take a look at how to declare that exact same class using ease.js:
@float Figure, f:class-easejs
@verbatim
var Class = require( 'easejs' ).Class;
const { Class } = require( 'easejs' );
// or: var Class = require( 'easejs' ).Class;
var MyClass = Class(
const MyClass = Class(
{
'public prop': 'foobar',
'public getProp': function()
'public getProp'()
{
return this.prop;
}
} );
// create a new instance of the class and execute doStuff()
var foo = MyClass();
const foo = MyClass();
console.log( foo.getProp() ); // outputs "foobar"
@end verbatim
@caption{Basic anonymous class declaration using ease.js}
@ -244,7 +245,7 @@ later on.
@item
ease.js's class module is imported using @code{require()} in the above
example. If using ease.js client-side (@pxref{Client-Side Include}), you
can instead use @samp{var Class = easejs.Class}. From this point on,
can instead use @samp{const @{Class@} = easejs}. From this point on,
importing the module will not be included in examples.
@end itemize
@ -284,19 +285,19 @@ In the majority of cases, this works fine in ease.js
@float Figure, f:method-chain
@verbatim
var Foo = Class( 'Foo',
const Foo = Class( 'Foo',
{
'public beginning': function()
'public beginning'()
{
return this;
},
'public middle': function()
'public middle'()
{
return this;
},
'public end': function()
'public end'()
{
// ...
}
@ -320,17 +321,17 @@ A callback, for example:
@float Figure, f:method-this-callback
@verbatim
var Foo = Class( 'Foo',
const Foo = Class( 'Foo',
{
'private _foo': 'good',
'private _foo': 'good',
'public beginning': function( c )
'public beginning'( c )
{
// XXX: `this' is the private visibility object
c( this );
},
'public end': function()
'public end'()
{
return this._foo;
}
@ -338,7 +339,7 @@ A callback, for example:
// result: 'bad'
Foo()
.beginning( function( self )
.beginning( self =>
{
// has access to internal state
self._foo = 'bad';
@ -365,17 +366,17 @@ To solve this problem,
@float Figure, f:method-callback-inst
@verbatim
var Foo = Class( 'Foo',
const Foo = Class( 'Foo',
{
'private _foo': 'good',
'public beginning': function( c )
'public beginning'( c )
{
// OK
c( this.__inst );
},
'public end': function()
'public end'()
{
return this._foo;
}
@ -383,7 +384,7 @@ To solve this problem,
// result: 'good'
Foo()
.beginning( function( self )
.beginning( self =>
{
// sets public property `_foo', since `self' is now the public
// visibility object
@ -406,7 +407,7 @@ the common act of creating anonymous functions in JavaScript:
@float Figure, f:anon-func
@verbatim
// anonymous
var myFunc = function() {};
const myFunc = function() {};
// named
function myNamedFunc() {};
@ -447,8 +448,8 @@ is functionally no difference between named and anonymous classes.}
@float Figure, f:class-named
@verbatim
var MyFoo = Class( 'MyFoo', {} ),
foo = MyFoo();
const MyFoo = Class( 'MyFoo', {} );
const foo = MyFoo();
// call non-existent method
foo.baz();
@ -484,10 +485,10 @@ Implementation}), using a @code{__construct}@tie{}method:
@float Figure, f:constructor
@verbatim
var Foo = Class( 'Foo',
const Foo = Class( 'Foo',
{
// may also use `construct`; see below
__construct: function( name )
// may also use `constructor`; see below
__construct( name )
{
console.log( 'Hello, ' + name + '!' );
}
@ -518,7 +519,7 @@ This method name may also be used prior to ES6.
@float Figure, f:constructor-es6
@verbatim
// ECMAScript 6 syntax
let Foo = Class( 'Foo',
const Foo = Class( 'Foo',
{
// you may still use __construct if you'd prefer, as shown above
constructor( name )
@ -558,9 +559,9 @@ If you wish to prevent a class from being instantiated,
@float Figure, f:constructor-prevent
@verbatim
var Foo = Class( 'Foo',
const Foo = Class( 'Foo',
{
__construct: function( name )
constructor( name )
{
throw Error( "Cannot instantiate class Foo" );
}
@ -614,9 +615,9 @@ Consider the following example:
@float Figure, f:class-tmp
@verbatim
// new instance of anonymous class
var foo = Class(
const foo = Class(
{
'public bar': function()
'public bar'()
{
return 'baz';
}
@ -654,20 +655,18 @@ or chain of methods, then are immediately discarded.
@float Figure, f:inst-tmp
@verbatim
// retrieve the name from an instance of Foo
var name = Foo().getName();
const name = Foo().getName();
// method chaining
var car = VehicleFactory()
const car = VehicleFactory()
.createBody()
.addWheel( 4 )
.addDoor( 2 )
.build();
// temporary class with callback
HttpRequest( host, port ).get( path, function( data )
{
console.log( data );
} );
HttpRequest( host, port )
.get( path, data => console.log( data ) );
// Conventionally (without ease.js), you'd accomplish the above using
// the 'new' keyword. You may still do this with ease.js, though it is
@ -828,41 +827,41 @@ classes using ease.js?
@float Figure, f:inheritance
@verbatim
// our parent class (supertype)
var Dog = Class( 'Dog',
const Dog = Class( 'Dog',
{
'virtual public walk': function()
'virtual public walk'()
{
console.log( 'Walking the dog' );
},
'public bark': function()
'public bark'()
{
console.log( 'Woof!' );
}
} );
// subclass (child), as a named class
var LazyDog = Class( 'LazyDog' ).extend( Dog,
const LazyDog = Class( 'LazyDog' ).extend( Dog,
{
'override public walk': function()
'override public walk'()
{
console.log( 'Lazy dog refuses to walk.' );
}
} );
// subclass (child), as an anonymous class
var TwoLeggedDog = Dog.extend(
const TwoLeggedDog = Dog.extend(
{
'override public walk': function()
'override public walk'()
{
console.log( 'Walking the dog on two feet' );
}
} );
// supertype override is implicitly virtual
var ReallyLazyDog = LazyDog.extend(
const ReallyLazyDog = LazyDog.extend(
{
'override public walk': function()
'override public walk'()
{
// ...
}
@ -948,12 +947,12 @@ method inherited from the parent.
@float Figure, f:using-inherited-members
@verbatim
var LazyDog = Class( 'LazyDog' ).extend( Dog,
const LazyDog = Class( 'LazyDog' ).extend( Dog,
{
/**
* Bark when we're poked
*/
'virtual public poke': function()
'virtual public poke'()
{
this.bark();
}
@ -994,9 +993,9 @@ this dog lazy, but he's rather moody.
@float Figure, f:super-method
@verbatim
var AngryDog = Class( 'AngryDog' ).extend( LazyDog,
const AngryDog = Class( 'AngryDog' ).extend( LazyDog,
{
'public poke': function()
'public poke'()
{
// augment the parent method
console.log( 'Grrrrrr...' );
@ -1048,14 +1047,14 @@ to the overridden @code{poke} method (in this case, @code{LazyDog.poke}):
@float Figure, f:arbitrary-super-method
@verbatim
var AngryDog = Class( 'AngryDog' ).extend( LazyDog,
const AngryDog = Class( 'AngryDog' ).extend( LazyDog,
{
'public poke': function()
'public poke'()
{
// ...
},
'public pokeWithDeliciousBone': function()
'public pokeWithDeliciousBone'()
{
// invoke LazyDog.poke
this.poke.super.call( this );
@ -1179,9 +1178,9 @@ It doesn't matter what instance of @var{Dog}---be it a @var{LazyDog} or
@float Figure, f:polymorphism-easejs
@verbatim
var DogTrainer = Class( 'DogTrainer',
const DogTrainer = Class( 'DogTrainer',
{
'public __construct': function( dog )
constructor( dog )
{
this.assertIsA( Dog, dog );
}
@ -1271,36 +1270,36 @@ Let's take a look at an example.
@float Figure, f:vis-esc
@verbatim
var Foo = Class(
const Foo = Class(
{
'virtual protected canEscalate': 'baz',
'virtual protected escalateMe'( arg )
{
'virtual protected canEscalate': 'baz',
console.log( 'In escalateMe' );
},
'virtual protected escalateMe': function( arg )
{
console.log( 'In escalateMe' );
},
'virtual public cannotMakeProtected': function()
{
}
} ),
SubFoo = Foo.extend(
'virtual public cannotMakeProtected'()
{
/**
* Escalating a property means redefining it
*/
'public canEscalate': 'baz',
}
} );
/**
* We can go protected -> public
*/
'public escalateMe': function( arg )
{
// simply call the parent method
this.__super( arg );
}
} );
const SubFoo = Foo.extend(
{
/**
* Escalating a property means redefining it
*/
'public canEscalate': 'baz',
/**
* We can go protected -> public
*/
'public escalateMe'( arg )
{
// simply call the parent method
this.__super( arg );
}
} );
@end verbatim
@caption{Visibility can be escalated}
@end float
@ -1322,10 +1321,10 @@ With GNU ease.js, error subtyping is transparent:
@float Figure, f:error-extend
@verbatim
var MyError = Class( 'MyError' )
const MyError = Class( 'MyError' )
.extend( Error, {} );
var e = MyError( 'Foo' );
const e = MyError( 'Foo' );
e.message; // Foo
e.name; // MyError
@ -1387,7 +1386,7 @@ recommended way of creating an @var{Error} subtype in ECMAScript:
@verbatim
function ErrorSubtype( message )
{
var err = new Error();
const err = new Error();
this.name = 'ErrorSubtype';
this.message = message || 'Error';
@ -1471,7 +1470,7 @@ Therefore, we will use a static property of class @var{BigBang}.
@float Figure, f:static-ex
@verbatim
var BigBang = Class( 'BigBang',
const BigBang = Class( 'BigBang',
{
/**
* Number of big bangs that has occurred
@ -1493,7 +1492,7 @@ Therefore, we will use a static property of class @var{BigBang}.
*
* @return {BigBang} new big bang
*/
'public static fromBraneCollision': function( brane_set )
'public static fromBraneCollision'( brane_set )
{
// do initialization tasks...
@ -1508,7 +1507,7 @@ Therefore, we will use a static property of class @var{BigBang}.
*
* @return {BigBang} new big bang
*/
'public static fromBigCrunch': function( crunch )
'public static fromBigCrunch'( crunch )
{
// do initialization tasks...
@ -1521,7 +1520,7 @@ Therefore, we will use a static property of class @var{BigBang}.
*
* @return {number} total number of big bangs
*/
'public static getTotalCount': function()
'public static getTotalCount'()
{
return this.$('_count');
}
@ -1535,7 +1534,7 @@ Therefore, we will use a static property of class @var{BigBang}.
*
* @return {undefined}
*/
__construct: function( type, data )
constructor( type, data )
{
this._type = type;
@ -1549,8 +1548,8 @@ Therefore, we will use a static property of class @var{BigBang}.
} );
// create one of each
var brane_bang = BigBang.fromBraneCollision( branes ),
crunch_bang = BigBang.fromBigCrunch( crunch_incident );
const brane_bang = BigBang.fromBraneCollision( branes );
const crunch_bang = BigBang.fromBigCrunch( crunch_incident );
console.log( "Total number of big bangs: %d", BigBang.getTotalCount() );
// Total number of big bangs: 2
@ -1593,13 +1592,13 @@ The final rule above is not true when the situation is reversed. Non-static
methods @emph{can} call static methods through use of the @var{__self}
object, which is a reference to the class itself. That is, @var{this} in a
static method is the same object as @var{this.__self} in a non-static
method. This is demonstrated by @code{getTotalCount()}
method. This is demonstrated by @code{getTotalCount}
@verbatim
this.$('_count')
@end verbatim
and @code{__construct()}.
and @code{#construct}.
@verbatim
this.__self.$('_count')
@ -1630,7 +1629,7 @@ acts as a getter, as in @ref{f:static-ex}'s @code{getTotalCount()}:
@end verbatim
If the second argument is provided, it acts as a setter, as in
@code{__construct()}:
@code{#construct}:
@verbatim
this.__self.$( '_count',
@ -1649,13 +1648,12 @@ omitted. Consider the following example:
@float Figure, f:static-accessor
@verbatim
var Foo = Class( 'Foo',
{
'public static bar': 'baz',
},
const Foo = Class( 'Foo',
{
'public static bar': 'baz',
} );
SubFoo = Class( 'SubFoo' ).extend( Foo, {} )
;
const SubFoo = Class( 'SubFoo' ).extend( Foo, {} );
// correct
Foo.$( 'bar, 'baz2' );
@ -1700,9 +1698,9 @@ mounts from @file{/etc/fstab}:
'private _mountPoints': [],
__construct: function()
constructor()
{
var data = fs.readFileSync( this.$('_PATH') );
const data = fs.readFileSync( this.$('_PATH') );
this._parseMountPoints( data );
},
@ -1876,7 +1874,7 @@ others. We could define this API in a @code{Socket} interface:
@float Figure, f:interface-def
@verbatim
var Socket = Interface( 'Socket',
const Socket = Interface( 'Socket',
{
'public connect': [ 'host', 'port' ],
@ -1894,20 +1892,20 @@ We can then provide any number of @code{Socket} implementations:
@float Figure f:interface-impl
@verbatim
var WebSocket = Class( 'WebSocket' ).implement( Socket ).extend(
{
'public connect': function( host, port )
{
// ...
},
// ...
} ),
SomeCustomSocket = Class.implement( Socket ).extend(
const WebSocket = Class( 'WebSocket' ).implement( Socket ).extend(
{
'public connect'( host, port )
{
// ...
} );
},
// ...
} );
const SomeCustomSocket = Class.implement( Socket ).extend(
{
// ...
} );
@end verbatim
@caption{Implementing an interface}
@end float
@ -1917,22 +1915,18 @@ polymorphically:
@float Figure, f:interface-poly
@verbatim
var ChatClient = Class(
const ChatClient = Class(
{
'private _socket': null,
__construct: function( socket )
constructor( socket )
{
// only allow sockets
if ( !( Class.isA( Socket, socket ) ) )
{
throw TypeError( 'Expected socket' );
}
this.assertIsA( Socket, socket );
this._socket = socket;
},
'public sendMessage': function( channel, message )
'public sendMessage'( channel, message )
{
this._socket.send( {
channel: channel,
@ -1972,7 +1966,7 @@ allow us to do something like @samp{some_socket.on( 'receive', function()
@float Figure, f:interface-impl-multi
@verbatim
var AnotherSocket = Class.implement( Socket, Event ).extend(
const AnotherSocket = Class.implement( Socket, Event ).extend(
{
'public connect': // ...
@ -2085,7 +2079,7 @@ Class( 'Dialog',
{
'private _factory': null,
__construct: function( factory )
constructor( factory )
{
if ( !( Class.isA( WidgetFactory, factory ) ) )
{
@ -2095,10 +2089,10 @@ Class( 'Dialog',
this._factory = factory;
},
'public open': function()
'public open'()
{
// before we open the dialog, we need to create and add the widgets
var btn = this._factory.createButtonWidget( 'btn_ok', "OK" );
const btn = this._factory.createButtonWidget( 'btn_ok', "OK" );
// ...
},
@ -2128,11 +2122,11 @@ subtypes:
@verbatim
AbstractClass( 'WidgetFactory',
{
'public createButtonWidget': function( id, label )
'public createButtonWidget'( id, label )
{
// note that this is a call to an abstract method; the
// implementation is not yet defined
var widget = this.getNewButtonWidget();
const widget = this.getNewButtonWidget();
// perform common initialization tasks
widget.setId( id );
@ -2175,7 +2169,7 @@ Class( 'JqueryUiWidgetFactory' )
.extend( WidgetFactory,
{
// concrete method
'protected getNewButtonWidget': function()
'protected getNewButtonWidget'()
{
// ...
},
@ -2233,43 +2227,43 @@ design patterns.
@float Figure, f:method-proxy-use
@verbatim
var Pidgin = Class( 'Pidgin',
const Pigeon = Class( 'Pigeon',
{
'private _name': 'Flutter',
'public cheep': function( chirp )
'public cheep'( chirp )
{
return this._name + ": cheep " + chirp;
}
'public rename': function( name )
'public rename'( name )
{
this._name = ''+name;
return this;
}
} );
var IratePidginCheep = Class( 'IratePidginCheep',
const IratePigeonCheep = Class( 'IratePigeonCheep',
{
'private _pidgin': null,
'private _pigeon': null,
__construct: function( pidgin )
constructor( pigeon )
{
this._pidgin = pidgin;
this._pigeon = pigeon;
}
// add our own method
'public irateCheep': function( chirp )
'public irateCheep'( chirp )
{
return this._pidgin.cheep( chirp ).toUpperCase();
return this._pigeon.cheep( chirp ).toUpperCase();
},
// retain original methods
'proxy cheep': '_pidgin',
'proxy rename': '_pidgin',
'proxy cheep': '_pigeon',
'proxy rename': '_pigeon',
} );
var irate = IratePidginCheep( Pidgin() );
const irate = IratePigeonCheep( Pigeon() );
irate.cheep( 'chirp' );
// "Flutter: cheep chirp"
@ -2279,7 +2273,7 @@ irate.irateCheep( 'chop' );
// "BUTTER: CHEEP CHOP"
@end verbatim
@caption{Using the @code{proxy} keyword to proxy @code{cheep} and
@code{rename} method calls to the object stored in property @code{_pidgin}.}
@code{rename} method calls to the object stored in property @code{_pigeon}.}
@end float
Consider some object @code{O} whoose class uses method proxies.

View File

@ -163,7 +163,7 @@ have been done for you.
@float Figure, f:inc-serverside
@verbatim
/** example-include.js **/
var easejs = require( 'easejs' );
const easejs = require( 'easejs' );
@end verbatim
@caption{Including ease.js via require()}
@end float

View File

@ -36,7 +36,7 @@ generated by ease.js may be instantiated either with or without the
@float Figure, f:interop-new
@verbatim
var Foo = Class( { /*...*/ } );
const Foo = Class( { /*...*/ } );
// both of these are equivalent
Foo();
@ -61,7 +61,7 @@ prototype of the subtype's constructor, as so:
@float Figure, f:interop-protochain-incorrect
@verbatim
var Foo = Class( { /*...*/ } );
const Foo = Class( { /*...*/ } );
// extending class as a prototype
function SubFoo() {};
@ -78,7 +78,7 @@ all classes:
@float Figure, f:interop-protochain
@verbatim
var Foo = Class( { /*...*/ } );
const Foo = Class( { /*...*/ } );
// extending class as a prototype
function SubFoo()
@ -138,13 +138,13 @@ work as expected:
@float Figure, f:typecheck-protosub
@verbatim
var Foo = Class( {} );
const Foo = Class( {} );
function SubFoo() {};
SubFoo.prototype = Foo.asPrototype();
SubFoo.constructor = Foo;
var SubSubFoo = Class.extend( SubFoo, {} );
const SubSubFoo = Class.extend( SubFoo, {} );
// vanilla ECMAScript
( new Foo() ) instanceof Foo; // true
@ -189,11 +189,11 @@ try to kill it (although that'd make for amusing gameplay).
@float figure, f:interface-croak
@verbatim
var Enemy = Interface( { croak: [] } ),
Toad = Interface( { croak: [] } ),
const Enemy = Interface( { croak: [] } );
const Toad = Interface( { croak: [] } );
AnEnemy = Class.implement( Enemy ).extend( /*...*/ ),
AToad = Class.implement( Toad ).extend( /*...*/ );
const AnEnemy = Class.implement( Enemy ).extend( /*...*/ );
const AToad = Class.implement( Toad ).extend( /*...*/ );
// GNU ease.js does not consider these interfaces to be equivalent
Class.isA( Enemy, AnEnemy() ); // true
@ -228,14 +228,14 @@ create ad-hoc instances of sorts:
@float figure, f:interface-objlit
@verbatim
var enemy = { croak: function() { /* ... */ ) },
toad = { croak: function() { /* ... */ ) };
const enemy = { croak() { /* ... */ ) };
const toad = { croak() { /* ... */ ) };
defeatEnemy( enemy ); // okay; duck typing
defeatEnemy( toad ); // okay; duck typing
// TypeError: object has no method 'croak'
defeatEnemy( { moo: function() { /*...*/ } } );
defeatEnemy( { moo() { /*...*/ } } );
function defeatEnemy( enemy )
{
@ -293,31 +293,31 @@ those members.
@float Figure, f:interface-compat
@verbatim
var Duck = Interface( {
const Duck = Interface( {
quack: [ 'str' ],
waddle: [],
} );
// false; no quack
Class.isA( Duck, { waddle: function() {} } );
Class.isA( Duck, { waddle() {} } );
// false; quack requires one parameter
Class.isA( Duck, {
quack: function() {},
waddle: function() {},
quack() {},
waddle() {},
} );
// true
Class.isA( Duck, {
quack: function( str ) {},
waddle: function() {},
quack( str ) {},
waddle() {},
} );
// true
function ADuck() {};
ADuck.prototype = {
quack: function( str ) {},
waddle: function() {},
quack( str ) {},
waddle() {},
};
Class.isA( Duck, ( new ADuck() ) );
@end verbatim
@ -335,21 +335,18 @@ interfaces. Consider, for example, a system that uses @code{XMLHttpRequest}:
@float Figure, f:interface-xmlhttp
@verbatim
// modeled around XMLHttpRequest
var HttpRequest = Interface(
const HttpRequest = Interface(
{
abort: [],
open: [ 'method', 'url', 'async', 'user', 'password' ],
send: [],
} );
var FooApi = Class(
const FooApi = Class(
{
__construct: function( httpreq )
constructor( httpreq )
{
if ( !( Class.isA( HttpRequest, httpreq ) ) )
{
throw TypeError( "Expecting HttpRequest" );
}
this.assertIsA( HttpRequest, httpreq );
// ...
}

View File

@ -240,7 +240,7 @@ Class( 'Dog',
// ...
'public walk': function()
'public walk'()
{
this.stand();
this._moveFrontLeg( 0 );
@ -249,7 +249,7 @@ Class( 'Dog',
this._moveBackLeg( 0 );
},
'protected stand': function()
'protected stand'()
{
if ( this.isSitting() )
{
@ -257,17 +257,17 @@ Class( 'Dog',
}
},
'public rollOver': function()
'public rollOver'()
{
this._body.roll();
},
'private _moveFrontLeg': function( leg )
'private _moveFrontLeg'( leg )
{
this._legs.front[ leg ].move();
},
'private _moveBackLeg': function( leg )
'private _moveBackLeg'( leg )
{
this._legs.back[ leg ].move();
},
@ -299,7 +299,7 @@ are not available outside the class.
@float Figure, f:encapsulation-call-priv
@verbatim
var dog = Dog();
const dog = Dog();
dog._moveFrontLeg( 1 );
// TypeError: Object #<Dog> has no method '_moveFrontLeg'
@ -324,12 +324,12 @@ explore that approach:
@float Figure, f:encapsulation-inherit-priv
@verbatim
var two_legged_dog = Class( 'TwoLeggedDog' ).extend( Dog,
const two_legged_dog = Class( 'TwoLeggedDog' ).extend( Dog,
{
/**
* This won't override the parent method.
*/
'private _moveFrontLeg': function( leg )
'private _moveFrontLeg'( leg )
{
// don't do anything
return;
@ -392,12 +392,12 @@ another subtype, @var{LazyDog}, which refuses to stand.
@float Figure, f:encapsulation-inherit-prot
@verbatim
var lazy_dog = Class( 'LazyDog' ).extend( Dog,
const lazy_dog = Class( 'LazyDog' ).extend( Dog,
{
/**
* Overrides parent method
*/
'protected stand': function()
'protected stand'()
{
// nope!
this.rollOver();