no-invalid-this
Запретить использование this в контекстах, где значение this равно undefined
В режиме строгости ключевые слова this вне классов или подобных объектов могут быть undefined и вызвать TypeError.
Подробности правила
Это правило предназначено для выявления использования ключевых слов this в контекстах, где значение this равно undefined.
Ключевые слова this на верхнем уровне скриптов всегда считаются допустимыми, потому что они ссылаются на глобальный объект независимо от режима строгости.
Ключевые слова this на верхнем уровне модулей ECMAScript всегда считаются недопустимыми, потому что их значение равно undefined.
Для this внутри функций это правило в основном проверяет, является ли функция, содержащая ключевое слово this, конструктором или методом. Обратите внимание, что стрелочные функции имеют лексическое this, и поэтому это правило проверяет их окружающие контексты.
Это правило определяет, является ли функция конструктором, по следующим условиям:
- Имя функции начинается с заглавной буквы.
- Функция назначена переменной, имя которой начинается с заглавной буквы.
- Функция является конструктором классов ES2015.
Это правило определяет, является ли функция методом, по следующим условиям:
- Функция находится на объекте-литерале.
- Функция назначена свойству.
- Функция является методом/геттером/сеттером классов ES2015.
И это правило разрешает ключевые слова this в функциях ниже:
- Метод
call/apply/bindфункции вызывается напрямую. - Функция является колбэком методов массива (например,
.forEach()) еслиthisArgзадано. - Функция имеет тег
@thisв своём комментарии JSDoc.
И это правило всегда разрешает ключевые слова this в следующих контекстах:
- На верхнем уровне скриптов.
- В инициализаторах полей класса.
- В статических блоках класса.
В противном случае это считается проблемой.
Это правило применяется только в режиме строгости. С "parserOptions": { "sourceType": "module" } в конфигурации ESLint ваш код находится в режиме строгости даже без директивы "use strict".
Примеры неверного кода для этого правила в режиме строгости:
/*eslint no-invalid-this: "error"*/
"use strict";
(function() {
.a = 0;
baz(() => );
})();
function foo() {
.a = 0;
baz(() => );
}
var foo = function() {
.a = 0;
baz(() => );
};
foo(function() {
.a = 0;
baz(() => );
});
var obj = {
aaa: function() {
return function foo() {
// There is in a method `aaa`, but `foo` is not a method.
.a = 0;
baz(() => );
};
}
};
foo.forEach(function() {
.a = 0;
baz(() => );
});
Примеры правильного кода для этого правила в режиме строгости:
/*eslint no-invalid-this: "error"*/
"use strict";
this.a = 0;
baz(() => this);
function Foo() {
// OK, this is in a legacy style constructor.
this.a = 0;
baz(() => this);
}
class Bar {
constructor() {
// OK, this is in a constructor.
this.a = 0;
baz(() => this);
}
}
var obj = {
foo: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
var obj = {
foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
var obj = {
get foo() {
// OK, this is in a method (this function is on object literal).
return this.a;
}
};
var obj = Object.create(null, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
Object.defineProperty(obj, "foo", {
value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
});
Object.defineProperties(obj, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
function Foo() {
this.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
baz(() => this);
};
}
obj.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
Foo.prototype.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
class Baz {
// OK, this is in a class field initializer.
a = this.b;
// OK, static initializers also have valid this.
static a = this.b;
foo() {
// OK, this is in a method.
this.a = 0;
baz(() => this);
}
static foo() {
// OK, this is in a method (static methods also have valid this).
this.a = 0;
baz(() => this);
}
static {
// OK, static blocks also have valid this.
this.a = 0;
baz(() => this);
}
}
var foo = (function foo() {
// OK, the `bind` method of this function is called directly.
this.a = 0;
}).bind(obj);
foo.forEach(function() {
// OK, `thisArg` of `.forEach()` is given.
this.a = 0;
baz(() => this);
}, thisArg);
/** @this Foo */
function foo() {
// OK, this function has a `@this` tag in its JSDoc comment.
this.a = 0;
}
Параметры
Это правило имеет объект параметров с одним параметром:
-
"capIsConstructor": false(по умолчаниюtrue) отключает предположение, что функция, имя которой начинается с заглавной буквы, является конструктором.
capIsConstructor
По умолчанию это правило всегда разрешает использование this в функциях, имена которых начинаются с заглавной буквы, и анонимных функциях, присвоенных переменной, имя которой начинается с заглавной буквы, предполагая, что эти функции используются в качестве конструкторов.
Установите "capIsConstructor" в false, если вы хотите, чтобы эти функции обрабатывались как «обычные» функции.
Примеры неверного кода для этого правила с "capIsConstructor" параметром, установленным в false:
/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/
"use strict";
function Foo() {
.a = 0;
}
var bar = function Foo() {
.a = 0;
}
var Bar = function() {
.a = 0;
};
Baz = function() {
.a = 0;
};
Примеры правильного кода для этого правила с "capIsConstructor" параметром, установленным в false:
/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/
"use strict";
obj.Foo = function Foo() {
// OK, this is in a method.
this.a = 0;
};
Когда не следует использовать это правило
Если вы не хотите получать уведомления об использовании ключевого слова this за пределами классов или подобных объектов, вы можете безопасно отключить это правило.
Обработка TypeScript
Это правило безопасно отключить при использовании TypeScript, так как компилятор TypeScript выполняет эту проверку.
Обратите внимание, что технически TypeScript выполнит проверку только если включены флаги strict или noImplicitThis. Эти флаги включены в большинстве проектов TypeScript, так как считаются лучшей практикой.
Версия
Это правило было введено в ESLint v1.0.0-rc-2.
Ссылки
© OpenJS Foundation and other contributors
Licensed under the MIT License.
https://eslint.org/docs/latest/rules/no-invalid-this