Por que JSHINT está reclamando que esta é uma violação estrita?

98

Acho que pode ser uma duplicata de Violação Estrita usando essa palavra-chave e revelando o padrão do módulo

Eu tenho este código:

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) está reclamando. Diz "Violação estrita". para a linha destacada:

insira a descrição da imagem aqui

Meu uso Function.call()e a referência à instância são de alguma forma inadequados?

Isso é considerado um estilo ruim?

Cheeso
fonte
Diz apenas "Violação estrita", sem qualquer mensagem de erro detalhada?
stivlo,
Não consigo reproduzir o problema, rodei o código através de JSHint e JSLint e não parece reclamar de nada.
Peter Olson,
54
Observe que isso seria muito mais fácil de diagnosticar se você não tentasse formar uma linha ridícula: P.
Domenic,
1
Eu vi isso em outra pergunta (não consigo encontrar agora). Tem a ver com o uso de this. Não tenho ideia de por que JSLint chamaria de Violação Estrita, mas sei que se você não definir o thisvalor de uma função, ela estará undefinedno modo estrito. Claramente você está definindo this, então não deve ser um problema.
user113716
2
Você pode ignorar essas possíveis violações estritas com "-W040":trueno config json, mas como o json não tem comentários, você não pode dizer a ninguém por que ele está lá.
kojiro

Respostas:

124

JSHint diz "Possível violação estrita" porque você está usando thisdentro de algo que, até onde sabemos, não é um método.

No modo não estrito, a chamada gotoPage(5)seria vinculada thisao objeto global ( windowno navegador). No modo estrito, thisestaria undefined, e você teria problemas.

Presumivelmente, você quer chamar essa função com um thiscontexto vinculado , por exemplo, gotoPage.bind(myObj)(5)ou gotoPage.call(myObj, 5). Nesse caso, você pode ignorar JSHint, pois não gerará nenhum erro. Mas, está dizendo a você que seu código não está claro para quem o lê, porque usar thisdentro de algo que não é obviamente um método é bastante confuso. Seria melhor simplesmente passar o objeto como parâmetro:

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
fonte
12
Mesmo assim, acho que eles estão enganando um pouco na descrição. Mesmo thisque acabe sendo undefined, o problema real não é apenas uma violação de modo estrito . Eles fariam melhor em dar um aviso dizendo que thispode estar undefinedno "modo estrito", levando a um TypeError(ou algo).
user113716
11
@ ripper234 na verdade, é por isso que sempre uso em event.currentTargetvez de this.
Domenic
4
Que diretiva de configuração posso adicionar .jshintrcpara desabilitar essa verificação?
callum
7
@callum "validthis": true
Brett
18
Use /* jshint validthis: true */se você tiver apenas um casal e não quiser mudar para todos os casos.
knownasilya
93

Recebi esta mensagem para uma função que não começava com letra maiúscula.

"use strict";

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


// ---> just fine (note the capital S in Something)
function Something() {
    this.test = "";
}
amenthes
fonte
28
Eu observaria que o jshint provavelmente está assumindo, devido à convenção, que Somethingé um construtor devido ao S maiúsculo e, portanto, deve ser chamado com new. Fazer isso define thisser um novo objeto baseado em `Something.prototype '. Provavelmente, devido a essa suposição, ela não gera o possível aviso de violação estrito.
Andy Merts
4
Eu tive esse erro em um provedor AngularJS, portanto, nomes de métodos com maiúsculas e minúsculas são esperados e eu usei minúsculas com camelo. Fixo.
Deminetix
Eu tive o problema semelhante, ao ter um nome de função apenas em minúsculas, renomeando usando uma maiúscula.
GibboK
Não use a primeira letra maiúscula porque também é um construtor, você enfrentará outro problema. em vez de, você pode usar: var fnAbc = function () {this.test = ""}
Hieu Tran AGI
A letra maiúscula não muda nada no funcionamento interno da função. É apenas algo que os programadores geralmente fazem dessa maneira para transmitir significado. Em outras palavras: este não é um problema tecnológico, mas de comunicação entre homens.
amenthes
9

Se você declarar a função como uma variável em vez de usar a declaração de função padrão, jshint não sinalizará isso como uma violação estrita. Então você pode fazer o seguinte -

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
fonte
0

Se estiver tentando implementar um método, você pode atribuir ao protótipo:

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

JSHint não avisará quando a função estiver sendo atribuída.

Flimm
fonte
Ainda não é bom o suficiente. ClassName.prototype.myMethod = myMethod;e definiu o método abaixo. Você ainda receberá um erro, embora myMethod esteja corretamente vinculado.
Jefftopia 01 de