Чому 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()а потім посилання на екземпляр якимось чином недоречне?

Це вважається поганим стилем?


Це говорить лише "Суворе порушення" без детального повідомлення про помилку?
stivlo

Я не можу відтворити проблему, я запустив код через JSHint та JSLint, і, здається, не скаржитися ні на що.
Пітер Олсон

54
Зауважте, що це було б набагато простіше діагностувати, якби ви не намагалися втиснути його в смішний однолінійний: P.
Доменік

1
Я бачив це в іншому запитанні (зараз не можу його знайти). Це пов'язано з використанням this. Я не знаю, чому JSLint назвав би це суворим порушенням, але я знаю, що якщо ви не визначите thisзначення функції, вона буде undefinedв суворому режимі. Ви чітко визначаєте this, тому це не повинно бути проблемою.
користувач113716

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(або чогось).
користувач113716

11
@ ripper234 дійсно, тому я завжди використовую event.currentTargetзамість цього this.
Доменік

4
Яку конфігураційну директиву можна додати, .jshintrcщоб відключити цю перевірку?
callum

7
@callum "validthis": правда
Бретт

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 = "";
}

28
Я зауважу, що jshint, ймовірно, припускає, що внаслідок конвенції, що Somethingце конструктор завдяки капіталу S, і тому його слід називати використанням new. Це визначає thisяк новий об'єкт на основі `Something.prototype '. Це, найімовірніше, пов'язане з таким припущенням, що воно не викликає можливого суворого попередження про порушення.
Енді Мертс

4
У мене була помилка у постачальника AngularJS, тому очікуються назви методів верхнього регістру, і у мене був нижній регістр. Виправлено.
Deminetix

У мене була аналогічна проблема, коли маючи ім'я функції лише малі, перейменувавши за допомогою капіталу.
GibboK

Не використовуйте першу букву з великої літери, оскільки це також конструктор, ви зіткнетеся з іншою проблемою. замість цього, ви можете використовувати: var fnAbc = function () {this.test = ""}
Hieu Tran AGI

Велика літера не змінює нічого щодо внутрішнього функціонування функції. Це просто те, що програмісти зазвичай роблять так, щоб передати значення. Іншими словами: це не технологічна проблема, а одна з комунікацій між людьми.
амент

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 не попередить, коли функція призначена.


Все ще недостатньо добре. ClassName.prototype.myMethod = myMethod;, потім визначили метод нижче. Ви все одно отримуєте помилку, навіть якщо myMethod правильно пов'язаний.
Jefftopia
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.