Почему JSHINT жалуется, что это строгое нарушение?

98

Я думаю, что это может быть дубликат строгого нарушения с использованием этого ключевого слова и раскрытием шаблона модуля

У меня есть такой код:

function gotoPage(s){
    if(s<=this.d&&s>0){this.g=s; this.page((s-1)*this.p.size);}
}

function pageChange(event, sorter) {
    var dd = event.currentTarget;
    gotoPage.call(sorter, dd[dd.selectedIndex].value);
}

И JSHINT (JSLINT) жалуется. Там написано «Строгое нарушение». для выделенной строки:

введите описание изображения здесь

Является ли мое использование Function.call()экземпляра и последующее обращение к нему как-то неуместным?

Считается ли это плохим стилем?

Чизо
источник
Говорится ли только «Строгое нарушение», без подробного сообщения об ошибке?
Стивло 07
Я не могу воспроизвести проблему, я прогнал код через JSHint и JSLint, и вроде бы ни на что не жаловался.
Питер Олсон
54
Обратите внимание, что это было бы намного легче диагностировать, если бы вы не пытались втиснуть это в нелепую однострочную строку: P.
Доменик
1
Я видел это в другом вопросе (сейчас не могу найти). Это связано с использованием this. Я понятия не имею, почему JSLint назвал бы это строгим нарушением, но я знаю, что если вы не определите thisзначение функции, она будет undefinedв строгом режиме. Ясно, что вы определяете this, так что это не должно быть проблемой.
user113716 07
2
Вы можете игнорировать эти возможные строгие нарушения с помощью "-W040":trueв конфигурации json, но поскольку json не имеет комментариев, вы не можете никому сказать, почему он там.
kojiro

Ответы:

124

JSHint говорит: «Возможное строгое нарушение», потому что вы используете thisвнутри что-то, что, насколько он может судить, не является методом.

В нестрогом режиме вызов gotoPage(5)будет привязан thisк глобальному объекту ( windowв браузере). В строгом режиме thisбыли бы undefined, и у вас были бы проблемы.

Предположительно, вы хотите вызвать эту функцию с привязанным thisконтекстом, например, gotoPage.bind(myObj)(5)или gotoPage.call(myObj, 5). В этом случае вы можете игнорировать JSHint, так как вы не создадите никаких ошибок. Но он говорит вам, что ваш код непонятен всем, кто его читает, потому что использование thisвнутри чего-то, что не является очевидным методом, довольно запутанно. Лучше просто передать объект в качестве параметра:

function gotoPage(sorter, s) {
    if (s <= sorter.d && s > 0) {
        sorter.g = s;

        sorter.page((s - 1) * sorter.p.size);
    }
}

function pageChange(event, sorter) {
    var dd = event.currentTarget;
    gotoPage(sorter, dd[dd.selectedIndex].value);
}
Доменик
источник
12
Тем не менее, я думаю, что они немного вводят в заблуждение в описании. Даже если thisэто в конечном итоге undefined, то фактическая проблема не только строгий режим нарушения. Им лучше было бы дать предупреждение, сказав, что это thisможет быть undefinedв "строгом режиме", что приведет к TypeError(или чему-то).
user113716 07
11
@ ripper234 действительно, поэтому я всегда использую event.currentTargetвместо this.
Domenic
4
В какую директиву конфигурации я могу добавить, .jshintrcчтобы отключить эту проверку?
Каллум
7
@callum "validthis": true
Бретт
18
Используйте, /* jshint validthis: true */если у вас всего пара и вы не хотите менять в каждом случае.
knownasilya
93

У меня было это сообщение для функции, которая не начиналась с заглавной буквы.

"use strict";

// ---> strict violation
function something() {
    this.test = "";
}


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}
Amenthes
источник
28
Я хотел бы отметить, что jshint, вероятно, предполагает, из-за соглашения, что Somethingэто конструктор из-за заглавной буквы S, и поэтому его следует вызывать с помощью new. Это определяет thisновый объект, основанный на Something.prototype. Скорее всего, это связано с тем, что это не вызывает предупреждения о возможном строгом нарушении.
Энди Мертс
4
У меня была эта ошибка у поставщика AngularJS, поэтому имена методов должны быть в верхнем регистре, а у меня был нижний регистр. Исправлена.
Deminetix
У меня была аналогичная проблема, когда имя функции было только в нижнем регистре, переименование с использованием заглавной буквы.
GibboK 09
Не используйте первую заглавную букву, потому что это тоже конструктор, вы столкнетесь с другой проблемой. вместо этого вы можете использовать: var fnAbc = function () {this.test = ""}
Hieu Tran AGI
Заглавная буква ничего не меняет во внутренней работе функции. Программисты обычно так делают, чтобы передать смысл. Другими словами: это не технологическая проблема, а проблема общения между хоманами.
amenthes
9

Если вы объявляете функцию как переменную вместо использования стандартного объявления функции, jshint не будет отмечать это как строгое нарушение. Итак, вы можете сделать следующее -

var gotoPage = function (s){
    if(s<=this.d&&s>0){this.g=s; this.page((s-1)*this.p.size);}
};


var pageChange = function (event, sorter) {
    var dd = event.currentTarget;
    gotoPage.call(sorter, dd[dd.selectedIndex].value);
};
Асулайман
источник
0

Если вы пытаетесь реализовать метод, вы можете вместо этого назначить прототипу:

ExampleClassName.protytpe.gotoPage = function gotoPage(s){
  // code using this
};

JSHint не будет предупреждать, когда функция назначается.

Flimm
источник
Все еще недостаточно хорошо. ClassName.prototype.myMethod = myMethod;, а затем определил метод ниже. Вы по-прежнему получаете сообщение об ошибке, даже если myMethod привязан правильно.
Джеффтопия 01