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
Changes from 7 commits
00d0733
bf5bff4
7e60929
6885fca
de1f864
3eca8d2
7a9d923
be86168
ca32a82
cf053cc
f790902
c233d58
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,22 @@ | ||
# Suggest using arrow functions as callbacks. (prefer-arrow-callback) | ||
# Suggest using ES6 arrow functions to describe callbacks (prefer-arrow-callback) | ||
|
||
Arrow functions are suited to callbacks, because: | ||
Arrow functions can be an attractive alternative to function expressions, when describing callbacks or function arguments. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is very nitpicky, but I think a comma is unnecessary here: |
||
|
||
- `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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "This is an upgrade from using |
||
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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"*/ | ||
|
@@ -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"*/ | ||
|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be clearer if we replace |
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; }); | ||
|
@@ -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') |
There was a problem hiding this comment.
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 likeSuggest using ES6 arrow functions for callbacks (prefer-arrow-callback)
?There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!