版本

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() {
    this.a = 0;
    baz(() => this);
})();

function foo() {
    this.a = 0;
    baz(() => this);
}

var foo = function() {
    this.a = 0;
    baz(() => this);
};

foo(function() {
    this.a = 0;
    baz(() => this);
});

var 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);
});

此规则在严格模式下**正确**代码示例

在在线运行中打开
/*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() {
    this.a = 0;
}

var bar = function Foo() {
    this.a = 0;
}

var Bar = function() {
    this.a = 0;
};

Baz = function() {
    this.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 的编译器会强制执行此检查。

请注意,从技术上讲,只有在启用了 strictnoImplicitThis 标志的情况下,TypeScript 才会捕获此错误。由于它们被认为是最佳实践,因此大多数 TypeScript 项目中都启用了这些标志。

版本

此规则在 ESLint v1.0.0-rc-2 中引入。

资源

更改语言