no-invalid-this
禁止在 this
值为 undefined
的上下文中使用 this
在严格模式下,类或类对象外部的 this
关键字可能为 undefined
并引发 TypeError
。
规则详情
此规则旨在标记在 this
值为 undefined
的上下文中使用 this
关键字的情况。
脚本中的顶级 this
始终被认为有效,因为它引用全局对象,而与严格模式无关。
ECMAScript 模块中的顶级 this
始终被认为无效,因为其值为 undefined
。
对于函数内部的 this
,此规则基本上检查包含 this
关键字的函数是否为构造函数或方法。请注意,箭头函数具有词法 this
,因此此规则检查其封闭上下文。
此规则根据以下条件判断函数是否为构造函数
- 函数名称以大写字母开头。
- 函数被分配给一个以大写字母开头的变量。
- 函数是 ES2015 类 的构造函数。
此规则根据以下条件判断函数是否为方法
- 函数位于对象字面量上。
- 函数被分配给一个属性。
- 函数是 ES2015 类 的方法/ getter/ setter。
并且此规则允许以下函数中的 this
关键字
- 函数的
call/apply/bind
方法被直接调用。 - 如果提供了
thisArg
,则函数是数组方法(例如.forEach()
)的回调函数。 - 函数在其 JSDoc 注释中具有
@this
标记。
并且此规则始终允许以下上下文中的 this
关键字
- 在脚本的顶层。
- 在类字段初始化器中。
- 在类静态块中。
否则被视为问题。
此规则**仅**在严格模式下应用。在 ESLint 配置中使用 "parserOptions": { "sourceType": "module" }
时,即使没有 "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 的编译器会强制执行此检查。
请注意,从技术上讲,只有在启用了 strict
或 noImplicitThis
标志的情况下,TypeScript 才会捕获此错误。由于它们被认为是最佳实践,因此大多数 TypeScript 项目中都启用了这些标志。
版本
此规则在 ESLint v1.0.0-rc-2 中引入。