diff --git a/docs/rules/no-underscore-dangle.md b/docs/rules/no-underscore-dangle.md index f78f24874e7..b4f89c99fc0 100644 --- a/docs/rules/no-underscore-dangle.md +++ b/docs/rules/no-underscore-dangle.md @@ -24,6 +24,14 @@ This rule aims to eliminate the use of dangling underscores in identifiers. Array of variable names that are permitted to be used with underscore. If provided, it must be an `Array`. +#### allowAfterThis + +```json +"no-underscore-dangle": [2, { "allowAfterThis": true }] +``` + +This option allows usage of dangled variables as members of `this`. + The following patterns are considered problems: ```js @@ -53,7 +61,13 @@ var foo_; foo._bar(); ``` +```js +/*eslint no-underscore-dangle: [2, { "allowAfterThis": true }]*/ + +var a = this.foo_; +this._bar(); +``` + ## When Not To Use It If you want to allow dangling underscores in identifiers, then you can safely turn this rule off. - diff --git a/lib/rules/no-underscore-dangle.js b/lib/rules/no-underscore-dangle.js index 4c11ff0387a..61590cf4a46 100644 --- a/lib/rules/no-underscore-dangle.js +++ b/lib/rules/no-underscore-dangle.js @@ -11,7 +11,9 @@ module.exports = function(context) { - var ALLOWED_VARIABLES = context.options[0] && context.options[0].allow ? context.options[0].allow : []; + var options = context.options[0] || {}; + var ALLOWED_VARIABLES = options.allow ? options.allow : []; + var allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false; //------------------------------------------------------------------------- // Helpers @@ -100,9 +102,11 @@ module.exports = function(context) { * @private */ function checkForTrailingUnderscoreInMemberExpression(node) { - var identifier = node.property.name; + var identifier = node.property.name, + isMemberOfThis = node.object.type === "ThisExpression"; if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && + !(isMemberOfThis && allowAfterThis) && !isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) { context.report(node, "Unexpected dangling \"_\" in \"" + identifier + "\"."); } @@ -129,6 +133,9 @@ module.exports.schema = [ "items": { "type": "string" } + }, + "allowAfterThis": { + "type": "boolean" } }, "additionalProperties": false diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index aab43d5957e..056d2668232 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -29,7 +29,8 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "var _foo = 1", options: [{ allow: ["_foo"] }]}, { code: "var __proto__ = 1;", options: [{ allow: ["__proto__"] }]}, { code: "foo._bar;", options: [{ allow: ["_bar"] }]}, - { code: "function _foo() {}", options: [{ allow: ["_foo"] }]} + { code: "function _foo() {}", options: [{ allow: ["_foo"] }]}, + { code: "this._bar;", options: [{allowAfterThis: true}]} ], invalid: [ { code: "var _foo = 1", errors: [{ message: "Unexpected dangling \"_\" in \"_foo\".", type: "VariableDeclarator"}] }, @@ -37,6 +38,7 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "function _foo() {}", errors: [{ message: "Unexpected dangling \"_\" in \"_foo\".", type: "FunctionDeclaration"}] }, { code: "function foo_() {}", errors: [{ message: "Unexpected dangling \"_\" in \"foo_\".", type: "FunctionDeclaration"}] }, { code: "var __proto__ = 1;", errors: [{ message: "Unexpected dangling \"_\" in \"__proto__\".", type: "VariableDeclarator"}] }, - { code: "foo._bar;", errors: [{ message: "Unexpected dangling \"_\" in \"_bar\".", type: "MemberExpression"}] } + { code: "foo._bar;", errors: [{ message: "Unexpected dangling \"_\" in \"_bar\".", type: "MemberExpression"}] }, + { code: "this._prop;", errors: [{ message: "Unexpected dangling \"_\" in \"_prop\".", type: "MemberExpression"}] } ] });