D&CO

Les décorateurs d'ES2016

http://hadrien.eu

Préambulle

ES62015

arrow => 'function'

...spread

...rest

Class

`templates ${literal}`

*generators

Class

class Something extends Thing {
  constructor (Service) {
    this.Service = Service;
  }
  
  get thing () {
    return 'thing';
  }
  
  doSomething () {
    return this.Service.do(this.thing);
  }

  static getSomething () {
    return 'something';
  }
}
class
constructor
get
doSomething
static

Transpiler

// […]
var Something = (function (_Thing) {
  _inherits(Something, _Thing);

  function Something(Service) {
    _classCallCheck(this, Something);

    _get(Object.getPrototypeOf(Something.prototype), 'constructor', this).call(this);
    this.Service = Service;
  }

  _createClass(Something, [{
    key: 'doSomething',
    value: function doSomething() {
      return this.Service['do'](this.thing);
    }
  }, {
    key: 'thing',
    get: function get() {
      return 'thing';
    }
  }], [{
    key: 'getSomething',
    value: function getSomething() {
      return 'something';
    }
  }]);

  return Something;
})(Thing);
Object.defineProperty(Target, key, {
  configurable: true,
  enumerable: true,
  value: 'value',
  writable: true
  // For setters and getters:
  get: function () {},
  set: function () {}
};

ES72016

Propriétés de classes

class Something extends Thing {
  static aStaticProperty = 'something';
  aProperty = 42;
}

Décorateurs

Exemple

class MainController {
  constructor (Service) {
    this.Service = Service;

    Object.defineProperty(this, 'cantTouchThis', {
      value: 'hammer',
      writable: false,
      enumerable: true,
      configurable: true
    });
  }

  get things () {
    return this.Service.get();
  }
}
MainController.inject = [Service];
SomeRandomFramework.addController('mainCtrl', MainController);
@controller('mainCtrl')
class MainController {
  @inject Service;
  @readonly cantTouchThis = 'hammer';

  get things () {
    return this.Service.get();
  }
}

HowToBasic

function controller (name) {
  return (Target) {
    SomeRandomFramework.addController('mainCtrl', Target);
  };
}

function readonly (Target, key, descriptor) {
  descriptor.writable = false;
}

function inject (Target, key, descriptor) {
  return {
    get: () => SomeRandomFramework.injector.get(key)
  };
}

Décorateur de classe

function decorate (Target) {
  // Play with Target
};

@decorate
class Test {}

Décorateur de propriété

function decorate (Target, key, descriptor) {
  // Play with Target,
  // change the property definition descriptor
};

class Test {
  @decorate myProperty = 'foo';
}

Marouflette

function decorateWithOptions ({foo, bar}) {
  function decorate (Target, key, descriptor) {
    // if (foo) {
    //   Target[foo] = bar;
    // }
  }
};

@decorateWithOptions()
class Test {
  @decorateWithOptions({ foo: true, bar: 'bar' }) myProperty;
}

IRL

import {controller, inject, readonly} from './decorators';

@controller('mainCtrl')
class MainController {
  @inject Service;
  @readonly cantTouchThis = 'hammer';

  get things () {
    return this.Service.get();
  }
}

THE END

http://hadrien.eu

D&Co

By Hadrien Eu