Domanda

Quando ho convalidare il seguente codice con JSLint ottengo i seguenti errori.

function displayMegaDropDown() {
"use strict";
var liMegaPosition, divMegaOffset;
liMegaPosition = jQuery(this).position();
divMegaOffset = { top: liMegaPosition.top + jQuery(this).height(), left: liMegaPosition.left };
jQuery(this).find("div").offset(divMegaOffset);

jQuery(this).addClass("hovering");
}

Problema alla linea 4 carattere 29: violazione Strict.

 liMegaPosition = jQuery(this).position();  

Problema alla linea 5 carattere 56: violazione Strict.

divMegaOffset = { top: liMegaPosition.top + jQuery(this).height(), left: liM...

Problema alla linea 6 carattere 12: violazione Strict.

jQuery(this).find("div").offset(divMegaOffset);

Problema alla linea di 8 caratteri 12: violazione Strict.

jQuery(this).addClass("hovering");

Sto indovinando che è a causa del l'uso di jQuery (questo), ma non capisco che cosa sostituirlo con. Si noti che questo è non , perché jQuery non è dichiarato come globale.

È stato utile?

Soluzione

Credo che il problema è che si utilizza this non all'interno di un metodo. Il seguente codice

/*global jQuery */
var myObj = {
    myNethod: function displayMegaDropDown() {
        "use strict";
        var ts = jQuery(this),
            liMegaPosition = ts.position(),
            divMegaOffset = {
                top: liMegaPosition.top + ts.height(),
                left: liMegaPosition.left
            };

        ts.find("div").offset(divMegaOffset);

        ts.addClass("hovering");
    }
};

o questa

/*global jQuery */
function displayMegaDropDown(t) {
    "use strict";
    var ts = jQuery(t),
        liMegaPosition = ts.position(),
        divMegaOffset = {
            top: liMegaPosition.top + ts.height(),
            left: liMegaPosition.left
        };

    ts.find("div").offset(divMegaOffset);

    ts.addClass("hovering");
}

vi darà errori o avvisi.

AGGIORNAMENTO : Un'altra versione, che è molto vicino al vostro originale, ha, inoltre, non errori o avvisi:

/*global jQuery */
var displayMegaDropDown = function () {
    "use strict";
    var ts = jQuery(this),
        liMegaPosition = ts.position(),
        divMegaOffset = {
            top: liMegaPosition.top + ts.height(),
            left: liMegaPosition.left
        };

    ts.find("div").offset(divMegaOffset);

    ts.addClass("hovering");
};

AGGIORNAMENTO 2 : Trovo interessante la domanda per la comprensione. Quindi guardo attraverso ECMAScript . Trovo quanto segue nella "allegato C (informativa) La modalità rigorosa di ECMAScript" (vedo meglio in versione HTML qui ):

Se questo viene valutata all'interno rigido codice modalità, allora il questo è il valore non costretto ad un oggetto. A questo valore Null o indefinito non è convertiti all'oggetto globale e valori primitivi non vengono convertiti a oggetti wrapper. Il questo valore passato tramite una chiamata di funzione (Incluse le chiamate effettuate utilizzando Function.prototype.apply e Function.prototype.call ) non costringere il passato questo valore a un oggetto (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4).

suppongo che è la ragione dell'errore JSLint.

Di causa se si desidera disattivare la modalità rigorosa del codice non avrà più errori:

/*global jQuery */
/*jslint sloppy: true */
function displayMegaDropDown() {
    var ts = jQuery(this),
        liMegaPosition = ts.position(),
        divMegaOffset = {
            top: liMegaPosition.top + ts.height(),
            left: liMegaPosition.left
        };

    ts.find("div").offset(divMegaOffset);

    ts.addClass("hovering");
}

AGGIORNAMENTO 3: Sembra che l'impossibilità di utilizzo del this nel funzione di istruzione e la possibilità di utilizzo del this nel espressione di una funzione sembra sospetto per molte persone. Oggi ho ricevuto un altro commento su questo. Così ho creato molto semplice demo

/*jslint devel: true */
(function () {
    'use strict';
    function test() {
        alert(this);
    }

    test();
}());

È possibile verificare lo qui che in IE9 l'avviso con il testo di visualizzazione demo "[Finestra oggetto]" e sulle versioni attuali di Chrome e Firefox si vedrà "non definito".

Quindi il problema con l'utilizzo di this in funzione di istruzione non è "una cosa JSLint". E 'vero problema che si dovrebbe prendere in considerazione durante lo sviluppo dei vostri programmi JavaScript.

Io personalmente preferisco usare espressione di una funzione e quasi mai usare più istruzioni di funzione . Penso che le persone che vengono da un altro linguaggi di programmazione (come me) troppo provano all'inizio di utilizzare la stessa costruzione che era buono nelle vostre lingue preferite. Solo più tardi si scopre che la definizione di variabili nel blocco è male (non ci sono portata a livello di blocco in JavaScript) e che istruzioni di funzione non è sempre la scelta migliore anche.

Altri suggerimenti

Non c'è modalità rigorosa violazione nel codice. Se ci fosse, si otterrebbe un errore di qualche tipo.

Per javascript nativo, this sarà undefined nel strict mode se la funzione contiene non viene richiamato uno:

  • come metodo di un oggetto
  • da Function.call o Function.apply
  • come costruttore

Questa è la ragione jshint si lamenta di esso.

Tuttavia, se la funzione viene utilizzato come un gestore di eventi per jQuery, jQuery forzerà la $(this) come oggetto jQuery del DOM che genera l'evento.

Per dimostrare questo, aprire la console di questa pagina ed eseguire il seguente codice.

(function(){
    "use strict";
    function event_handler() {
        $(this).css('background','red');
    }

    $('#content').on('click', 'table', event_handler);
})();

Fare clic su qualsiasi domanda o una risposta a questa pagina e si dovrebbe vedere lo sfondo diventa rosso.

Molto più facile! Basta usare ev.currentTarget invece di questo. E 'lo stesso che si può provare con ===

function event_handler(ev) {
    //var $el = $(this); // jshint - error
    var $el = $(ev.currentTarget); // is exactly the same as above
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top