no-invalid-this
禁止在 this 的值为 undefined 的上下文中使用 this
在严格模式下,类或类类似对象之外的 this 关键字可能是 undefined 并且会引发 TypeError。
🌐 Under the strict mode, this keywords outside of classes or class-like objects might be undefined and raise a TypeError.
规则详情
🌐 Rule Details
此规则旨在标记在 this 的值为 undefined 时使用 this 关键字的情况。
🌐 This rule aims to flag usage of this keywords in contexts where the value of this is undefined.
脚本中的顶层 this 始终被认为是有效的,因为它指的是全局对象,无论是否处于严格模式。
🌐 Top-level this in scripts is always considered valid because it refers to the global object regardless of the strict mode.
在 ECMAScript 模块中,顶层的 this 总是被认为是无效的,因为它的值是 undefined。
🌐 Top-level this in ECMAScript modules is always considered invalid because its value is undefined.
对于函数内部的 this,此规则基本上检查包含 this 关键字的函数是构造函数还是方法。请注意,箭头函数具有词法 this,因此此规则会检查它们的封闭上下文。
🌐 For this inside functions, this rule basically checks whether or not the function containing this keyword is a constructor or a method. Note that arrow functions have lexical this, and that therefore this rule checks their enclosing contexts.
该规则根据以下条件判断函数是否为构造函数:
🌐 This rule judges from following conditions whether or not the function is a constructor:
- 函数名以大写开头。
- 该函数被分配给以大写字母开头的变量。
- 该函数是 ES2015 Classes 的构造函数。
该规则从以下条件判断函数是否为方法:
🌐 This rule judges from following conditions whether or not the function is a method:
- 该函数位于对象字面上。
- 该函数被分配给一个属性。
- 该函数是 ES2015 类的方法/getter/setter。
这个规则允许在以下函数中使用 this 关键字:
🌐 And this rule allows this keywords in functions below:
- 函数的
call/apply/bind方法被直接调用。 - 如果提供了
thisArg,该函数就是数组方法(例如.forEach())的回调函数。 - 该函数的 JSDoc 注释中有
@this标签。
而且此规则始终允许在以下上下文中使用 this 关键字:
🌐 And this rule always allows this keywords in the following contexts:
- 在脚本的顶层。
- 在类字段初始值设定项中。
- 在类静态块中。
否则视为问题。
🌐 Otherwise are considered problems.
此规则仅在严格模式下适用。使用 ESLint 配置中的 "languageOptions": { "sourceType": "module" },即使没有 "use strict" 指令,你的代码也处于严格模式。
🌐 This rule applies only in strict mode.
With "languageOptions": { "sourceType": "module" } in the ESLint configuration, your code is in strict mode even without a "use strict" directive.
严格模式下该规则的错误代码示例:
🌐 Examples of incorrect code for this rule in strict mode:
/*eslint no-invalid-this: "error"*/
"use strict";
(function() {
this.a = 0;
baz(() => this);
})();
function foo() {
this.a = 0;
baz(() => this);
}
const bar = function() {
this.a = 0;
baz(() => this);
};
foo(function() {
this.a = 0;
baz(() => this);
});
const obj = {
aaa: function() {
return function foo() {
// There is in a method `aaa`, but `foo` is not a method.
this.a = 0;
baz(() => this);
};
}
};
foo.forEach(function() {
this.a = 0;
baz(() => this);
});
严格模式下该规则的正确代码示例:
🌐 Examples of correct code for this rule in strict mode:
/*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);
}
}
const obj = {
foo: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
const obj1 = {
foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
const obj2 = {
get foo() {
// OK, this is in a method (this function is on object literal).
return this.a;
}
};
const obj3 = 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);
}
}
const bar = (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;
}
选项
🌐 Options
此规则有一个对象选项,有一个选项:
🌐 This rule has an object option, with one option:
"capIsConstructor": false(默认true)禁止假设名称以大写字母开头的函数是构造函数。
capIsConstructor
默认情况下,该规则总是允许在名称以大写字母开头的函数中以及赋值给名称以大写字母开头的变量的匿名函数中使用 this,假设这些函数用作构造函数。
🌐 By default, this rule always allows the use of this in functions which name starts with an uppercase and anonymous functions that are assigned to a variable which name starts with an uppercase, assuming that those functions are used as constructor functions.
如果你希望那些函数被视为“常规”函数,请将 "capIsConstructor" 设置为 false。
🌐 Set "capIsConstructor" to false if you want those functions to be treated as ‘regular’ functions.
当 "capIsConstructor" 选项设置为 false 时,此规则的 错误 代码示例:
🌐 Examples of incorrect code for this rule with "capIsConstructor" option set to false:
/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/
"use strict";
function Foo() {
this.a = 0;
}
const bar = function Foo() {
this.a = 0;
}
const Bar = function() {
this.a = 0;
};
Baz = function() {
this.a = 0;
};
在 "capIsConstructor" 选项设置为 false 时,此规则的正确代码示例:
🌐 Examples of correct code for this rule with "capIsConstructor" option set to false:
/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/
"use strict";
obj.Foo = function Foo() {
// OK, this is in a method.
this.a = 0;
};
此规则还支持 TypeScript 类型语法。
🌐 This rule additionally supports TypeScript type syntax.
针对该规则的 错误 TypeScript 代码示例:
🌐 Examples of incorrect TypeScript code for this rule:
/*eslint no-invalid-this: "error"*/
function foo(bar: string) {
this.prop;
console.log(bar)
}
/** @this Obj */
foo(function() {
console.log(this);
z(x => console.log(x, this));
});
function foo() {
class C {
accessor [this.a] = foo;
}
}
针对该规则的 正确 TypeScript 代码示例:
🌐 Examples of correct TypeScript code for this rule:
/*eslint no-invalid-this: "error"*/
interface SomeType {
prop: string;
}
function foo(this: SomeType) {
this.prop;
}
class A {
a = 5;
b = this.a;
accessor c = this.a;
}
何时不使用
🌐 When Not To Use It
如果你不希望收到关于在类或类类似对象之外使用 this 关键字的通知,你可以安全地禁用此规则。
🌐 If you don’t want to be notified about usage of this keyword outside of classes or class-like objects, you can safely disable this rule.
由 TypeScript 处理
使用 TypeScript 时禁用此规则是安全的,因为 TypeScript 的编译器强制执行此检查。
Note that, technically, TypeScript will only catch this if you have the strict or noImplicitThis flags enabled. These are enabled in most TypeScript projects, since they are considered to be best practice.
版本
此规则是在 ESLint v1.0.0-rc-2 中引入。