2 * @fileoverview A rule to disallow `this` keywords outside of classes or class-like objects.
3 * @author Toru Nagashima
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const astUtils = require("./utils/ast-utils");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
23 description: "disallow `this` keywords outside of classes or class-like objects",
24 category: "Best Practices",
26 url: "https://eslint.org/docs/rules/no-invalid-this"
38 additionalProperties: false
44 const options = context.options[0] || {};
45 const capIsConstructor = options.capIsConstructor !== false;
47 sourceCode = context.getSourceCode();
50 * Gets the current checking context.
52 * The return value has a flag that whether or not `this` keyword is valid.
53 * The flag is initialized when got at the first time.
54 * @returns {{valid: boolean}}
55 * an object which has a flag that whether or not `this` keyword is valid.
57 stack.getCurrent = function() {
58 const current = this[this.length - 1];
62 current.valid = !astUtils.isDefaultThisBinding(
72 * Pushs new checking context into the stack.
74 * The checking context is not initialized yet.
75 * Because most functions don't have `this` keyword.
76 * When `this` keyword was found, the checking context is initialized.
77 * @param {ASTNode} node A function node that was entered.
80 function enterFunction(node) {
82 // `this` can be invalid only under strict mode.
84 init: !context.getScope().isStrict,
91 * Pops the current checking context from the stack.
94 function exitFunction() {
101 * `this` is invalid only under strict mode.
102 * Modules is always strict mode.
105 const scope = context.getScope(),
106 features = context.parserOptions.ecmaFeatures || {};
113 node.sourceType === "module" ||
114 (features.globalReturn && scope.childScopes[0].isStrict)
123 FunctionDeclaration: enterFunction,
124 "FunctionDeclaration:exit": exitFunction,
125 FunctionExpression: enterFunction,
126 "FunctionExpression:exit": exitFunction,
128 // Reports if `this` of the current context is invalid.
129 ThisExpression(node) {
130 const current = stack.getCurrent();
132 if (current && !current.valid) {
133 context.report({ node, message: "Unexpected 'this'." });