Define class method property with ES6 syntax

Viewed 189

In ES5 syntax, a class Foo with a method bar having a property flag can be defined like:

function Foo() {};
Foo.prototype.bar = function() { console.log('bar invoked'); };
Foo.prototype.bar.flag = true;

I could mix up ES5 and ES6 syntax and do:

class Foo {
  bar() {
    console.log('bar invoked');
  };
};
Foo.prototype.bar.flag = true;

Or using just ES6 syntax do:

class Foo {
  bar() {
    this.bar.flag = true;
    console.log('bar invoked');
  };
};

If I have to choose I'd go for second option but I dislike the redundancy in including the name of the method within it's definition. Is there a better way?

3 Answers

If you can go beyond ES2015 and do not afraid to use experimental things you could play with decorators. Babel repl.

class Foo {
  @flag
  bar() {
    console.log('bar invoked');
  };
};

function flag(target) {
  target.descriptor.value.flag = true;
  return target;
}


const foo = new Foo()

console.log(foo.bar.flag)

There's no declarative way to create a property on a method in JavaScript (it's quite a rare thing to do), so if you want to do that, you have to do it after-the-fact as in your second example. (Or your third, but that's repeated every time bar is called so it's a bit misleading and/or possibly not that useful.)

There's no way to reference the function being called using strict mode (remember that using classes makes strict mode automatic).

If you would ever want to do that, using ES5 "classes":

function Foo() {};
Foo.prototype.bar = function() {
  console.log('bar invoked');
  arguments.callee.flag = true;
};

Remember that arguments.callee is disabled in strict mode.

Related