Warum ist das illegal im Strict-Modus?
-
29-09-2019 - |
Frage
Ja, ja, ich weiß, Strict-Modus ist nicht um noch, aber wirklich, ich bin die Planung für die Zukunft ...
Also, warum ist dies:
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
... nicht in ES5 Strict-Modus erlaubt?
Oder bin falsch interpretiert ich? JSLint:
Problem at line 516 character 18: Strict violation.
Könnte es etwas ausführlicher sein, frage ich mich ...?
EDIT:
Um Verwirrung zu vermeiden, hier ist mehr der ursprünglichen Code:
function displayLegend() {
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
}
Lösung
Einige Trial-and-error dieses Codes in JSLint
"use strict";
var that="dd";
function $(x){return x;}
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
$(this);
zeigt mir, was los ist: Sie verwenden this
als Parameter. nicht auslösen den Fehler sowohl this
es zu that
s ändern.
Wie die Spezifikation sagt:
Wenn dieser im Strict-Modus-Code ausgewertet wird, dann wird der dieser Wert wird nicht auf ein Objekt dazu gezwungen. Ein dieses Wert null oder undefined ist nicht auf das globale Objekt umgewandelt und primitive Werte werden nicht in Wrapper-Objekte umgewandelt. Die dieses Wert über einen Funktionsaufruf übergeben (einschließlich Anrufe mit Function.prototype.apply und Function.prototype.call ) zu tun nicht zwingen, das übergebene dieses Wert auf ein Objekt ( 10.4.3 , 11.1.1 , 15.3.4.3 , 15.3.4.4 ). [Hervorhebung von mir]
Wie John Resig schreibt ,
Schließlich wird eine langjährige (und sehr ärgerlich) Fehler wurde behoben: Cases wo null oder nicht definiert ist, dazu gezwungen in das globale Objekt wird. Strict-Modus verhindert, dass jetzt diese aus geschieht und löst eine Ausnahme statt.
(function(){ ... }).call( null ); // Exception
Wie Sie zeigte, mit Ihrem Code-Zeile in einer Funktion Erklärung wirft einen Fehler in JSLint, während es in einer Funktion unter Verwendung des Ausdrucks nicht. Es sieht aus wie JSLint fälschlicherweise die Funktionsdeklaration analysiert, sieht this
, die in diesem Moment noch nicht definiert ist, und löst eine Ausnahme.
An diesem Punkt denke ich, ich habe Zitat Juriy Zaytsev ( 'kangax') :
Ist es wirklich egal?
Es ist gut, dass Strict-Modus zu verstehen, ist nicht erforderlich , ist aber lediglich eine Option. Es ist dort zu bieten strengere Regeln für diejenigen, die es braucht, und sind bereit, zu bewältigen (Und genießen) Folgen.
Update: Endlich finde ich eine Erklärung. Wenn Sie lesen dieses Themas , insbesondere von message # 1512 ab, werden Sie, dass
lesenDer Punkt von ES5 / streng zu verbieten undicht des globalen Objekts, etwas, das ES3 promiscuously tut. ES5 / strict tut einen Teil seiner Arbeit dynamisch, und einige seiner Arbeit statisch. JSLint tut all seinen statisch arbeiten, so dass es auch sein muss, restriktiv beste Hilfe, um Sie erhalten Ihr Programm richtig. [Douglas Crockford in # 1553]
Ich muss zugeben, dass er einen wichtigen Punkt hat sich hier: wenn Ihr Ziel ist die globale Namespace Verschmutzung zu vermeiden, sollten Sie nicht Funktionsdeklarationen verwenden, aber Funktionsausdrücke in einem privaten Namespace, sowieso. Aber ich stimme mit anderen in dem genannten Thread, dass die Fehlermeldung mehr explizit sein sollte (und wahrscheinlich auch eine Warnung wirft auf eine Funktionsdeklaration zu begegnen).
Andere Tipps
Nach was David Dorward sagte, fand ich etwas, das JSLint den Test besteht. Das ist geradezu merkwürdig, warum es das zu tun.
Bevor: (siehe Frage)
Nach:
var displayLegend = function () {
$('#'+ $(this).attr('id').replace('control-', 'legend-')).fadeIn();
};
EDIT:
Ich fragte Douglas Crockford:
JSLint erlaubt nur diese im strikten Modus Funktionen, die sind offensichtlich soll als Methoden aufgerufen werden. So Schreib
object.property = function () { ... this ... };
Dies bestätigt, was es in der Spezifikation sagt, es sei denn es ist viel klarer!