JSHint "Möglicher strenger Verstoß." bei Verwendung von `bind`

73

Betrachten Sie diesen einfachen Code:

"use strict";

var obj = {
    f: function() {
        this.prop = 'value';
        g.bind( this )();
    }
};

function g() {
    console.log( this.prop );
}

Wenn ich versuche, diesen Code zu validieren, gibt mir jshint den Fehler, Possible strict violation.wo ich anrufe console.log( this.prop );. Dies liegt daran, dass thisin einer Funktion im strengen Modus undefiniert ist.

Aber ich binde diese Funktion, bevor ich sie aufrufe, ebenso thiswie das richtige Objekt.

Ich verwende dieses "Entwurfsmuster", um ein Durcheinander des Hauptobjekts zu vermeiden. Wenn Sie die Eigenschaften in den Parametern übergeben, wird auch die Funktion unübersichtlich, daher lehne ich dies ab. Außerdem ist dies genau das, wofür es bindist.

Gibt es eine Möglichkeit für JSHint, mich dies tun zu lassen?

Florian Margaine
quelle
Ist das vielleicht ein Fehler in jshint?
Rlemon
1
Nun, es ist richtig, dass dies eine mögliche strenge Verletzung ist. Wenn es die bindAngelegenheit jedoch nicht analysieren kann, sollte es meiner Meinung nach eine Warnung bleiben, kein Fehler. Keine Ahnung ...
Florian Margaine
1
Aber wie du erwähnt hast; Dies ist kein Fehler, da Sie ihn zuerst gebunden haben, bevor Sie ihn aufrufen. Es ist wahrscheinlich auch nicht allzu hilfreich, wenn es eine Warnung ausspuckt, da dies der beabsichtigte Zweck von.bind()
rlemon
Ja ... Ich habe dieses Problem in der Jshint-Warteschlange geöffnet, aber vielleicht gibt es eine Konfigurationsmöglichkeit, um dies zu ändern? Deshalb habe ich die Frage gestellt: Um eine Problemumgehung zu finden (nicht zu hässlich), falls möglich.
Florian Margaine
"das ist genau das, wofür bind" - Nun, hier möchten Sie vielleicht einfach etwas tun g.call(this), denke ich. (Ich bin gmir jedoch nicht sicher, ob das Problem dadurch var g = function() { }.bind(obj)behoben wird .) Wenn Sie standardmäßig binden möchten , können Sie dies stattdessen tun , um jshint mit Beschwerden zu stoppen.
Pimvdb

Antworten:

128

Es ist äußerst schwierig, diesen Fall zu erkennen, ohne den Code auszuführen. Mit der Option können Sie validthisdiese Warnung unterdrücken:

"use strict";

var obj = {
    f: function() {
        this.prop = 'value';
        g.bind( this )();
    }
};

function g() {
    /*jshint validthis:true */
    console.log( this.prop );
}

Es ist zu beachten, dass jshint-Kommentare einen Funktionsumfang haben. Der Kommentar funktioniert also für die Funktion gund ihre inneren Funktionen, nicht nur für die nächste Zeile.

Anton Kovalyov
quelle
Muss ich diesen Kommentar vor jeder Zeile hinzufügen, in der ich ihn verwende this?
Florian Margaine
1
Nein, Optionen in JSHint sind funktionsbezogen. Dieser Kommentar funktioniert also innerhalb der Funktion gund ihrer inneren Funktionen (falls vorhanden).
Anton Kovalyov
9
Aber das Dumme ist, dass es sich nicht um eine mögliche Verletzung des strengen Modus handelt. Das Deklarieren einer Variable ohne das Schlüsselwort var wäre eine strikte Verletzung des Modus. Dies ist nur die falsche Warnung für einen Fehler, der sich aus dem Versuch ergeben kann, auf eine Eigenschaft von undefined zuzugreifen. Es ist ein potenzielles Problem im Zusammenhang mit dem strengen Modus, aber das Problem hätte nichts damit zu tun, dass tatsächlich strenge Modusregeln verletzt werden.
Erik Reppen
11
Oder fügen Sie " validthis " hinzu: true to your .jshintrc
Raine Revere
7
@Raine Dies deaktiviert jedoch die Überprüfung für Ihre gesamte Codebasis. Dies ist ein Sonderfall und sollte speziell behandelt werden, nicht für die gesamte Codebasis.
Florian Margaine
7

Sie können den gleichen Effekt auch erzielen, wenn Sie Ihren Code wie folgt ändern, um zu vermeiden, dass thisalle zusammen verwendet werden.

"use strict";

var obj = {
    f: function() {
        this.prop = 'value';
        g.bind( null, this )();
    }
};

function g(self) {
    console.log( self.prop );
}
George
quelle
3

Hier ist eine einfachere Lösung, die keine Änderung des Musters oder eines bestimmten Markups für jshint erfordert:

"use strict";

var obj = {
    f: function() {
        this.prop = 'value';
        G.bind( this )();
    }
};

function G() {
    console.log( this.prop );
}

jshint geht davon aus, dass Sie der Konvention folgen, dass Funktionen, die mit einem Großbuchstaben beginnen, Klassen sind, die instanziiert werden und immer thisverfügbar sind.

xgrtl
quelle
2
Ich denke, das verursacht einen ziemlichen Code-Geruch. Sie verwenden nur eine nicht verwandte Funktion von jshint, um es auszutricksen.
Ben
1

Versuchen:

"use strict";

var obj = {
    f: function() {
        this.prop = 'value';
        g.bind( this )();
    }
};

var g = function() {
    console.log( this.prop );
}
Michał Wojas
quelle
0

Dies ist ein anderes "Designmuster", wie Sie es ausdrücken. Es erreicht dasselbe, vermeidet jedoch das Problem vollständig.

"use strict";

function obj() {
    this.prop = '';
}

obj.prototype.f = function obj_f() {
    this.prop = 'value';
    this.g();
};

obj.prototype.g = function obj_g() {
    console.log( this.prop );
};

Sie würden es so aufrufen:

var myO = new obj();
myO.f();
George
quelle
Ich sagte in meiner Frage, dass ich dieses Muster vermeiden wollte :)
Florian Margaine
Dieses Muster ist nur dann unübersichtlich, wenn sich alle Ihre Skripte in einer Datei befinden. Sie können Bibliotheken wie require.js verwenden, um Ihren Code zu modularisieren.
George
Vielen Dank, ich weiß über require.js, webpack, browserify usw. Bescheid. Dies ist jedoch nicht Gegenstand dieser Frage.
Florian Margaine
+1. Diese Antwort beantwortet möglicherweise nicht die ursprüngliche Frage des OP, ist jedoch nützlich für andere, die Probleme mit dem Fehler "Möglicher strikter Verstoß" haben.
Necreaux