Dlaczego JSHINT narzeka, że ​​jest to surowe naruszenie?

98

Myślę, że może to być duplikat Strict Violation używający tego słowa kluczowego i ujawniający wzorzec modułu

Mam ten kod:

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) narzeka. Jest tam napisane „Surowe naruszenie”. dla podświetlonej linii:

wprowadź opis obrazu tutaj

Czy korzystanie z Function.call()instancji, a następnie odwoływanie się do niej, jest w jakiś sposób nieodpowiednie?

Czy to jest uważane za zły styl?

Ser
źródło
Czy wyświetla tylko „Ścisłe naruszenie” bez żadnego szczegółowego komunikatu o błędzie?
stivlo
Nie mogę odtworzyć problemu, uruchomiłem kod przez JSHint i JSLint i wydaje się, że nie narzeka na nic.
Peter Olson,
54
Zauważ, że byłoby to o wiele łatwiejsze do zdiagnozowania, gdybyś nie próbował wcisnąć go w absurdalną jedną linijkę: P.
Domenic
1
Widziałem to w innym pytaniu (nie mogę go teraz znaleźć). Ma to związek z używaniem this. Nie mam pojęcia, dlaczego JSLint nazwałby to Strict Violation, ale wiem, że jeśli nie zdefiniujesz thiswartości funkcji, będzie ona undefinedw trybie ścisłym. Najwyraźniej definiujesz this, więc nie powinno to stanowić problemu.
user113716
2
Można zignorować te możliwe ścisłe naruszeń ze "-W040":truew json config, ale ponieważ json nie ma komentarzy, nie można nikomu powiedzieć, dlaczego tam jest.
kojiro,

Odpowiedzi:

124

JSHint mówi „Możliwe ścisłe naruszenie”, ponieważ używasz thiswewnątrz czegoś, co, o ile może stwierdzić, nie jest metodą.

W trybie nieścisłym wywołanie gotoPage(5)wiązałoby się thisz obiektem globalnym ( windoww przeglądarce). W trybie ścisłym thisbyłoby undefinedi wpadłbyś w kłopoty.

Przypuszczalnie masz na myśli wywołanie tej funkcji z powiązanym thiskontekstem, np . gotoPage.bind(myObj)(5)Lub gotoPage.call(myObj, 5). Jeśli tak, możesz zignorować JSHint, ponieważ nie wygenerujesz żadnych błędów. Ale mówi ci, że twój kod jest niejasny dla każdego, kto go czyta, ponieważ użycie thiswewnątrz czegoś, co nie jest oczywiście metodą, jest dość zagmatwane. Lepiej byłoby po prostu przekazać obiekt jako parametr:

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);
}
Domenic
źródło
12
Mimo to myślę, że są one trochę mylące w opisie. Nawet jeśli thistak się stanie undefined, rzeczywisty problem nie jest tylko ścisłym naruszeniem trybu . Lepiej zrobiliby, ostrzegając, że thismoże to mieć miejsce undefinedw „trybie ścisłym”, prowadząc do TypeError(lub czegoś).
user113716
11
@ ripper234 rzeczywiście, dlatego zawsze używam event.currentTargetzamiast this.
Domenic
4
Do jakiej dyrektywy config mogę dodać, .jshintrcaby wyłączyć to sprawdzanie?
callum
7
@callum "validthis": true
Brett
18
Użyj, /* jshint validthis: true */jeśli masz tylko parę i nie chcesz się zmieniać w każdym przypadku.
knownasilya
93

Otrzymałem tę wiadomość dla funkcji, która nie zaczynała się wielką literą.

"use strict";

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


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}
amenty
źródło
28
Chciałbym zauważyć, że jshint prawdopodobnie zakłada, ze względu na konwencję, że Somethingjest konstruktorem ze względu na duże S i tak powinno być nazywane using new. Robiąc to, definiuje thissię jako nowy obiekt oparty na `Something.prototype '. Najprawdopodobniej wynika to z tego założenia, że ​​nie powoduje to ostrzeżenia o możliwym ścisłym naruszeniu.
Andy Merts
4
Wystąpił ten błąd u dostawcy AngularJS, dlatego oczekiwane są nazwy metod z dużymi literami wielbłąda i miałem małe litery. Naprawiony.
Deminetix
Miałem podobny problem, gdy miałem nazwę funkcji tylko małymi literami, zmieniając nazwę za pomocą stolicy.
GibboK,
Nie używaj dużej pierwszej litery, ponieważ jest to również konstruktor, napotkasz inny problem. zamiast tego możesz użyć: var fnAbc = function () {this.test = ""}
Hieu Tran AGI
Wielka litera nie zmienia nic w wewnętrznym działaniu funkcji. Jest to po prostu coś, co programiści zwykle robią w ten sposób, aby przekazać znaczenie. Innymi słowy: nie jest to problem technologiczny, ale problem komunikacji między homanami.
amenthes
9

Jeśli zadeklarujesz funkcję jako zmienną zamiast używać standardowej deklaracji funkcji, jshint nie oznaczy tego jako ścisłe naruszenie. Możesz więc wykonać następujące czynności -

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);
};
asulaiman
źródło
0

Jeśli próbujesz zaimplementować metodę, możesz zamiast tego przypisać ją do prototypu:

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

JSHint nie ostrzega, gdy funkcja jest przypisywana.

Flimm
źródło
Wciąż nie wystarczy. ClassName.prototype.myMethod = myMethod;, a następnie zdefiniował metodę poniżej. Nadal pojawia się błąd, mimo że myMethod jest poprawnie powiązany.
Jefftopia