Pourquoi JSHINT se plaint-il qu'il s'agit d'une violation stricte?

98

Je pense que cela peut être un double de Strict Violation en utilisant ce mot-clé et un modèle de module révélateur

J'ai ce code:

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

Et JSHINT (JSLINT) se plaint. Il dit "Violation stricte". pour la ligne en surbrillance:

entrez la description de l'image ici

Est-ce que mon utilisation de Function.call()l'instance, puis la référencer, est en quelque sorte inappropriée?

Est-ce considéré comme un mauvais style?

Cheeso
la source
Est-ce que cela dit seulement "Violation stricte", sans aucun message d'erreur détaillé?
stivlo
Je ne peux pas reproduire le problème, j'ai exécuté le code via JSHint et JSLint et il ne semble pas se plaindre de quoi que ce soit.
Peter Olson
54
Notez que ce serait beaucoup plus facile à diagnostiquer si vous n'essayiez pas de l'entasser dans un ridicule one-liner: P.
Domenic
1
J'ai vu cela dans une autre question (je ne peux pas le trouver pour le moment). Cela a à voir avec l'utilisation de this. Je ne sais pas pourquoi JSLint l'appellerait une violation stricte, mais je sais que si vous ne définissez pas la thisvaleur d'une fonction, elle sera undefineden mode strict. Vous définissez clairement this, donc cela ne devrait pas être un problème.
user113716
2
Vous pouvez ignorer ces éventuelles violations strictes avec "-W040":truedans la configuration json, mais comme json n'a pas de commentaires, vous ne pouvez dire à personne pourquoi il est là.
kojiro

Réponses:

124

JSHint dit "Violation stricte possible" parce que vous utilisez à l' thisintérieur quelque chose qui, pour autant qu'il sache, n'est pas une méthode.

En mode non strict, l'appel gotoPage(5)serait lié thisà l'objet global ( windowdans le navigateur). En mode strict, ce thisserait undefinedet vous auriez des ennuis.

Vraisemblablement, vous voulez appeler cette fonction avec un thiscontexte lié , par exemple gotoPage.bind(myObj)(5)ou gotoPage.call(myObj, 5). Si tel est le cas, vous pouvez ignorer JSHint, car vous ne générerez aucune erreur. Mais cela vous indique que votre code n'est pas clair pour quiconque le lit, car utiliser à l' thisintérieur de quelque chose qui n'est manifestement pas une méthode est assez déroutant. Il vaudrait mieux passer simplement l'objet en paramètre:

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
la source
12
Même ainsi, je pense qu'ils sont un peu trompeurs dans la description. Même si thiscela finit par l'être undefined, le problème réel n'est pas seulement une violation de mode strict . Ils feraient mieux de donner un avertissement en disant que cela thispeut être undefineden "mode strict", conduisant à un TypeError(ou quelque chose).
user113716
11
@ ripper234 en effet, c'est pourquoi j'utilise toujours à la event.currentTargetplace de this.
Domenic
4
À quelle directive de configuration puis-je ajouter .jshintrcpour désactiver cette vérification?
callum
7
@callum "validthis": true
Brett
18
À utiliser /* jshint validthis: true */si vous n'en avez que quelques-uns et que vous ne voulez pas changer pour chaque cas.
knownasilya
93

J'ai eu ce message pour une fonction qui ne commençait pas par une majuscule.

"use strict";

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


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}
amenthes
la source
28
Je noterais que jshint suppose probablement, en raison de la convention, qu'il Somethings'agit d'un constructeur en raison du capital S, et devrait donc être appelé using new. Cela définit thisêtre un nouvel objet basé sur «Something.prototype». C'est probablement en raison de cette hypothèse que cela ne soulève pas l'avertissement de violation stricte possible.
Andy Merts
4
J'ai eu cette erreur sur un fournisseur AngularJS, par conséquent, les noms de méthode en majuscule sont attendus et j'avais des minuscules de chameau. Fixé.
Deminetix
J'ai eu le même problème, en ayant un nom de fonction uniquement en minuscules, en renommant en utilisant une majuscule.
GibboK
N'utilisez pas la première lettre majuscule car c'est aussi un constructeur, vous serez confronté à un autre problème. au lieu de, vous pouvez utiliser: var fnAbc = function () {this.test = ""}
Hieu Tran AGI
La lettre majuscule ne change rien au fonctionnement interne de la fonction. C'est juste quelque chose que les programmeurs font généralement de cette façon pour transmettre du sens. En d'autres termes: ce n'est pas un problème technologique, mais un problème de communication entre homans.
amenthes le
9

Si vous déclarez la fonction comme une variable au lieu d'utiliser la déclaration de fonction standard, jshint ne marquera pas cela comme une violation stricte. Vous pouvez donc faire ce qui suit -

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
la source
0

Si vous essayez d'implémenter une méthode, vous voudrez peut-être l'attribuer au prototype à la place:

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

JSHint n'avertit pas lorsque la fonction est attribuée.

Flimm
la source
Pas encore assez bien. ClassName.prototype.myMethod = myMethod;, puis défini la méthode ci-dessous. Vous obtenez toujours une erreur même si myMethod est correctement lié.
Jefftopia