Recent Changes - Search:

edit SideBar

Extend

An accessor may specify that it extends another accessor in its setup() function by invoking:

  • extend(<string> name): Extend an accessor with the specified name.

This has the effect of implementing the interface of the other accessor, as if implement had been invoked, but in addition, it inherits all exported fields and functions of the specified accessor. Specifically, the exports property of the base accessor becomes the prototype of the exports property of the extending accessor.

For example, suppose a base accessor MyBase has the following:

  exports.initialize = function() {
    console.log('Initialize base accessor.');
  }

Then if an accessor specifies the following:

  exports.setup = function() {
    this.extend("MyBase");
  }

then it will inherit the exports.initialize() function of the base accessor.

Functions

An accessor may override any exported function of the base accessor by simply defining a function with the same name. Moreover, the override function can invoke the overridden function as in the following example:

  exports.initialize = function() {
    exports.ssuper.initialize.call(this);
    console.log('Initialize extending accessor.');
  };

When the initialize() function of the extended accessor is invoked, then the following will appear on the console:

  Initialize base accessor.
  Initialize extending accessor.

Notice that the exports property has a ssuper property that refers to the exports property of the base accessor, which is also the prototype of the exports property of the extending accessor. Thus, ssuper refers to the prototype.

Notice further that the initialize function is invoked using initialize.call(this). This ensures that while the base accessors initialize function is executing, the variable "this" refers to the extending accessor.

Input Handlers

An accessor can also override input handler functions. Suppose that a Base accessor has the following:

exports.inputHandler = function() {
   // Send true to output.
   this.send('output', true);
}
exports.initialize = function() {
   this.addInputHandler('input', this.exports.inputHandler.bind(this));
}

Notice that this.exports.inputHandler not exports.inputHandler is added as an input handler. Hence, a derived accessor that extends this base can override the input handler with the following code:

exports.inputHandler = function() {
   // Send false to output instead.
   this.send('output', false);
}

When the initialize function of the base accessor is invoked, it will actually add the derived accessor's handler rather than its own because "this" will refer to the derived accessor. In an instance of Derived, when an input arrives on 'input', the accessor will send false to 'output', not true as in the Base accessor.

If instead we had written in the base accessor

   this.addInputHandler('input', exports.inputHandler.bind(this));

then the override would not succeed. As with all JavaScript functions, exports.inputHandler is resolved in the scope in which initialize() is _defined_, not in the scope in which it _executes_. Therefore, exports.inputHandler refers to the 'inputHandler' property of the Base accessor. This latter pattern can be used to prevent extended accessors from overriding certain behavior.

Inputs, Outputs and Parameters

A derived accessor may modify the options of the inputs, outputs, and parameters of the extended accessor. For example, if MyBase has a parameter named foo, then

  exports.setup = function() {
    this.extend('MyBase');
    this.parameter('foo', {'value':43});
  }

modifies the default value of 'foo' from whatever it is in the base to 43.

Accessing Base Variables in a Derived Accessor

A derived accessor may read and write the values of variables in the parent accessor if the parent accessor declares the variables using exports. For example if the MyBase accessor has:

exports.socket = null;

Then derived accessors may refer to that variable with

exports.ssuper.socket

For example UDPSocketListener is extended by Moto360GestureListener and Moto360GestureListener uses exports.ssuper.socket.


Back to accessor specification

Edit - History - Print - Recent Changes - Search
Page last modified on September 14, 2017, at 05:11 pm