Skip to content

Instantly share code, notes, and snippets.

@ericelliott
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericelliott/a79a54e729f957b5debe to your computer and use it in GitHub Desktop.
Save ericelliott/a79a54e729f957b5debe to your computer and use it in GitHub Desktop.
Broken concise method name

Broken concise method names

There's a relatively common problem confusing users of ES6. This code demonstrates the issue.

const repeater = {
  name: 'Repeater',
  types: [
    { f: 'function' },
    { n: 'number' }
  ],
  repeat (f, n) {
    if (typeof f === 'function') {
      f();
    } else {
      throw new Error('repeat: A Function is required.');
    }

    n -= 1;
    if (!n) {
      return undefined;
    }

    return repeat(f, n);
  }
};

repeater.repeat(() => {console.log('foo');}, 10);

Output:

foo
ReferenceError: repeat is not defined

The problem is that unlike all typical function expressions, methods don't have lexical bindings that correspond to the function name identifier. In order for this to work, you have to use the form:

  repeat: function repeat (f, n) { //...
@ericelliott
Copy link
Author

There's a custom ESLint rule to catch this and help you fix it.

@RReverser
Copy link

There is absolutely no sense in doing return repeat(...) inside of method, since as soon as it's object method and not a regular function, you also want to pass this anyway, so it should be rather return this.repeat(...) which, in turn, works with concise methods perfectly.

@ericelliott
Copy link
Author

Using this.foo() is not compatible with deep recursion.

It doesn't work perfectly. JavaScript is dynamic. The host object could mutate, or the call may be delegated with .call() or .apply(). Also, this.repeat() isn't compatible with proper tail calls (it won't compile to a while loop), meaning that if the repeat value is too high, it will blow up the call stack and crash the program.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment