Perché JSHINT si lamenta che questa è una violazione severa?


98

Penso che questo possa essere un duplicato di Violazione severa usando questa parola chiave e rivelando il modello del modulo

Ho questo codice:

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

E JSHINT (JSLINT) si lamenta. Dice "Violazione severa". per la riga evidenziata:

inserisci qui la descrizione dell'immagine

Il mio uso Function.call()e quindi riferimento all'istanza è in qualche modo inappropriato?

Questo è considerato un cattivo stile?


Dice solo "Violazione rigorosa", senza alcun messaggio di errore dettagliato?
stivlo

Non riesco a riprodurre il problema, ho eseguito il codice tramite JSHint e JSLint e non sembra lamentarsi di nulla.
Peter Olson

54
Nota che questo sarebbe molto più facile da diagnosticare se non provassi a stiparlo in un ridicolo one-liner: P.
Domenic

1
L'ho visto in un'altra domanda (non riesco a trovarlo adesso). Ha a che fare con l'uso di this. Non ho idea del motivo per cui JSLint lo definirebbe una violazione rigorosa, ma so che se non si definisce il thisvalore di una funzione, sarà undefinedin modalità rigorosa. Chiaramente stai definendo this, quindi non dovrebbe essere un problema.
user113716

2
Puoi ignorare queste possibili violazioni severe con "-W040":truenel json di configurazione, ma poiché json non ha commenti, non puoi dire a nessuno perché è lì.
kojiro

Risposte:


124

JSHint dice "Possibile violazione severa" perché stai usando thisqualcosa che, per quanto può dire, non è un metodo.

In modalità non rigorosa, la chiamata gotoPage(5)si legherebbe thisall'oggetto globale ( windownel browser). In modalità rigorosa, thissarebbe undefined, e ti metteresti nei guai.

Presumibilmente, intendi chiamare questa funzione con un thiscontesto vincolato , ad esempio gotoPage.bind(myObj)(5)o gotoPage.call(myObj, 5). In tal caso, puoi ignorare JSHint, poiché non genererai alcun errore. Ma ti sta dicendo che il tuo codice non è chiaro a chiunque lo legga, perché l'uso thisall'interno di qualcosa che non è ovviamente un metodo è abbastanza confuso. Sarebbe meglio passare semplicemente l'oggetto come parametro:

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
Anche così, penso che siano un po 'fuorvianti nella descrizione. Anche se thisfinisce per esserlo undefined, il problema reale non è solo una violazione della modalità rigorosa . Farebbero meglio a dare un avvertimento dicendo che thispotrebbe essere undefinedquando in "modalità rigorosa", portando a un TypeError(o qualcosa del genere).
user113716

11
@ ripper234 in effetti, ecco perché uso sempre al event.currentTargetposto di this.
Domenic

4
Quale direttiva di configurazione posso aggiungere .jshintrcper disabilitare questo controllo?
callum

7
@callum "validthis": true
Brett

18
Usalo /* jshint validthis: true */se ne hai solo una coppia e non vuoi cambiare per ogni caso.
knownasilya

93

Ho ricevuto questo messaggio per una funzione che non iniziava con una lettera maiuscola.

"use strict";

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


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}

28
Vorrei notare che jshint probabilmente sta assumendo, a causa della convenzione, che Somethingè un costruttore a causa della S maiuscola, e quindi dovrebbe essere chiamato using new. In questo modo si definisce thisun nuovo oggetto basato su "Something.prototype". È molto probabilmente dovuto a questa ipotesi che non solleva il possibile avviso di violazione rigorosa.
Andy Merts

4
Ho riscontrato questo errore su un provider AngularJS, quindi sono previsti nomi di metodi in maiuscolo e cammello e ho avuto lettere in minuscolo. Fisso.
Deminetix

Ho avuto il problema simile, quando avevo un nome di funzione solo in minuscolo, rinominare usando una maiuscola.
GibboK

Non usare maiuscola perché è anche un costruttore, dovrai affrontare un altro problema. invece di, puoi usare: var fnAbc = function () {this.test = ""}
Hieu Tran AGI

La lettera maiuscola non cambia nulla sul funzionamento interno della funzione. È solo qualcosa che i programmatori di solito fanno in questo modo per trasmettere significato. In altre parole: questo non è un problema tecnologico, ma di comunicazione tra homans.
amenthes

9

Se dichiari la funzione come una variabile invece di usare la dichiarazione di funzione standard, jshint non la contrassegnerà come una violazione rigorosa. Quindi puoi fare quanto segue:

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

Se stai cercando di implementare un metodo, potresti invece voler assegnare al prototipo:

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

JSHint non avvisa quando la funzione viene assegnata.


Ancora non abbastanza buono. ClassName.prototype.myMethod = myMethod;, quindi ha definito il metodo di seguito. Ricevi ancora un errore anche se myMethod è associato correttamente.
Jefftopia
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.