Spec-Zone.ru › ESLint

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 функции вызывается напрямую.
  • Функция является callback-функцией метода массива (например, .forEach()), если передан thisArg.
  • В комментарии JSDoc функции есть тег @this.

Кроме того, это правило всегда разрешает ключевые слова this в следующих контекстах:

  • На верхнем уровне скриптов.
  • В инициализаторах полей класса.
  • В статических блоках класса.

Во всех остальных случаях это считается проблемой.

Это правило применяется только в строгом режиме. Если в конфигурации ESLint задан "languageOptions": { "sourceType": "module" }, ваш код работает в строгом режиме даже без директивы "use strict".

Примеры неправильного кода для этого правила в строгом режиме:

Открыть в Playground
/*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);
});

Примеры правильного кода для этого правила в строгом режиме:

Открыть в Playground
/*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;
}

Параметры

Это правило принимает объект параметров с одним параметром:

  • "capIsConstructor": false (по умолчанию true) отключает предположение, что функция, имя которой начинается с заглавной буквы, является конструктором.

capIsConstructor

По умолчанию это правило всегда разрешает использование this в функциях, имя которых начинается с заглавной буквы, и анонимных функциях, присвоенных переменной, имя которой начинается с заглавной буквы, предполагая, что эти функции используются как функции-конструкторы.

Установите "capIsConstructor" в значение false, если хотите, чтобы эти функции считались «обычными» функциями.

Примеры неправильного кода для этого правила, когда параметр "capIsConstructor" установлен в значение false:

Открыть в Playground
/*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:

Открыть в Playground
/*eslint no-invalid-this: ["error", { "capIsConstructor": false }]*/

"use strict";

obj.Foo = function Foo() {
    // OK, this is in a method.
    this.a = 0;
};

Это правило также поддерживает синтаксис типов TypeScript.

Примеры неправильного кода TypeScript для этого правила:

Открыть в Playground
/*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 для этого правила:

Открыть в Playground
/*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;
}

Когда не следует использовать это правило

Если вы не хотите получать уведомления об использовании ключевого слова 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API