Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Completely re-write allowUnboundThis option (fixes #8950) #9077

Merged
merged 12 commits into from Sep 1, 2017
Merged
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 30 additions & 14 deletions docs/rules/prefer-arrow-callback.md
@@ -1,15 +1,22 @@
# Suggest using arrow functions as callbacks. (prefer-arrow-callback)
# Suggest using ES6 arrow functions to describe callbacks (prefer-arrow-callback)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The word describe doesn't quite feel right to me. What do you think of making it something like Suggest using ES6 arrow functions for callbacks (prefer-arrow-callback)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also make sure this matches the metadata property in the rule itself!: https://github.com/eslint/eslint/blob/master/lib/rules/prefer-arrow-callback.js#L136

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I change the metadata property as part of this same PR? or do I need to create a new one to make them match?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do change the metadata on this same PR if you can. Thanks!


Arrow functions are suited to callbacks, because:
Arrow functions can be an attractive alternative to function expressions, when describing callbacks or function arguments.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very nitpicky, but I think a comma is unnecessary here: function expressions, when


- `this` keywords in arrow functions bind to the upper scope's.
- The notation of the arrow function is shorter than function expression's.
For example, arrow functions are bound to their surrounding scope/context automatically. This is an upgrade from using `bind()` and `this` to explicitly bind a function expression, which was the pre-ES6 standard for achieving similar scoping behavior.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This is an upgrade from using bind() and this" feels too opinionated for me. Maybe something like, "This makes them a less verbose alternative to using bind() and this" or even just "This allows them to be used as an alternative to using bind() and this", since you explain why below?


Additionally, arrow functions are:

- less verbose and easier to reason about.

- more robust and lexically bound regardless of where or when they are eventually invoked.

## Rule Details

This rule is aimed to flag usage of function expressions in an argument list.
This rule identifies function expressions being used as callbacks or function arguments, where upgrading to an arrow function would achieve identical results.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"where upgrading to an arrow function" doesn't feel like right here. How about "where using an arrow function" instead?


Instances where an arrow function would not achieve identical results will be ignored.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example of the cases this rule ignores would be helpful!


The following patterns are considered problems:
The following patterns **will** produce an error:

```js
/*eslint prefer-arrow-callback: "error"*/
Expand All @@ -18,7 +25,7 @@ foo(function(a) { return a; });
foo(function() { return this.a; }.bind(this));
```

The following patterns are not considered problems:
The following patterns **will not** produce an error:

```js
/*eslint prefer-arrow-callback: "error"*/
Expand All @@ -39,28 +46,33 @@ foo(function bar(n) { return n && n + bar(n - 1); });

## Options

This rule takes one optional argument, an object which is an options object.
Access further control over this rule's behavior via an options object.

Default: `{ allowNamedFunctions: false, allowUnboundThis: true }`

### allowNamedFunctions

This is a `boolean` option and it is `false` by default. When set to `true`, the rule doesn't warn on named functions used as callbacks.
This option accepts a `boolean` value and is `false` by default. When `false`, any named functions used as callbacks will produce a flag.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be clearer if we replace and is with that is.

When `true`, named functions will no longer produce a flag.

Examples of **correct** code for the `{ "allowNamedFunctions": true }` option:

```js
/*eslint prefer-arrow-callback: ["error", { "allowNamedFunctions": true }]*/
/*eslint prefer-arrow-callback: [ "error", { "allowNamedFunctions": true } ]*/

foo(function bar() {});
```

### allowUnboundThis

This is a `boolean` option and it is `true` by default. When set to `false`, this option allows the use of `this` without restriction and checks for dynamically assigned `this` values such as when using `Array.prototype.map` with a `context` argument. Normally, the rule will flag the use of `this` whenever a function does not use `bind()` to specify the value of `this` constantly.
By default `{ "allowUnboundThis": true }`, this option will allow function expressions containing `this` to be used as callbacks - as long as the function in question has not been explicitly bound.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't need the dash :)


`{ "allowUnboundThis": false }` prohibits using function expressions to describe callbacks entirely, without exception.

Examples of **incorrect** code for the `{ "allowUnboundThis": false }` option:

```js
/*eslint prefer-arrow-callback: ["error", { "allowUnboundThis": false }]*/
/*eslint prefer-arrow-callback: [ "error", { "allowUnboundThis": false } ]*/
/*eslint-env es6*/

foo(function() { this.a; });
Expand All @@ -72,6 +84,10 @@ someArray.map(function (itm) { return this.doSomething(itm); }, someObject);

## When Not To Use It

This rule should not be used in ES3/5 environments.
- In environments that have not yet adopted ES6 language features (ES3/5).

- In ES6+ environments that allow the use of function expressions when describing callbacks or function arguments.

## Further Reading

In ES2015 (ES6) or later, if you don't want to be notified about function expressions in an argument list, you can safely disable this rule.
- [More on ES6 arrow functions]('https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions')