Pregunta

Cuando valido el siguiente código con JSLint, recibo los siguientes errores.

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 en la línea 4 Carácter 29: Violación estricta.

 liMegaPosition = jQuery(this).position();  

Problema en la línea 5 Carácter 56: Violación estricta.

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

Problema en la línea 6 Carácter 12: Violación estricta.

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

Problema en la línea 8 Carácter 12: Violación estricta.

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

Supongo que se debe al uso de jQuery (esto), pero no entiendo con qué reemplazarlo. Tenga en cuenta que esto es no Porque JQuery no se declara como un global.

¿Fue útil?

Solución

Creo que el problema es que usas this no dentro de un método. El siguiente código

/*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 este

/*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");
}

No le dará errores ni advertencias.

ACTUALIZADO: Una versión más, que está muy cerca de su original, tampoco tiene errores ni advertencias:

/*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");
};

Actualizado 2: Encuentro la pregunta interesante para la comprensión. Entonces miro a través de Estándar de ECMAScript . Encuentro lo siguiente en el "Anexo C (informativo) el modo estricto de ECMAScript" (ver mejor en la versión HTML aquí):

Si este se evalúa dentro del código de modo estricto, entonces el este El valor no se coacciona a un objeto. A este valor de nulo o indefinido no se convierte al objeto global y los valores primitivos no se convierten en objetos de envoltura. los este Valor aprobado a través de una llamada de función (incluidas las llamadas realizadas usando Function.prototype.apply y Function.prototype.call) No coaccione el pasado este valor a un objeto (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4).

Supongo que es la razón del error JSLint.

De causa si apagaría el modo estricto, el código no tendrá más errores:

/*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");
}

Actualizado 3: Parece que la imposibilidad del uso de this en el instrucción de función y la posibilidad del uso de this en el Expresión de funciones Parece sospechoso para muchas personas. Hoy recibí un comentario más sobre esto. Entonces creé una demostración muy simple

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

    test();
}());

Puedes probarlo aquí que en IE9 la alerta de visualización de demostración con el texto [Ventana de objeto] y en las versiones actuales de Chrome y Firefox verá "indefinido".

Entonces el problema con el uso de this en instrucción de función no es "una cosa de jslint". Es un problema real que debe tener en cuenta durante el desarrollo de sus programas JavaScript.

Personalmente prefiero usar Expresión de funciones y casi nunca usas más declaraciones de funciones. Creo que las personas que provienen de otro programa de idiomas (como yo también) intentan al principio usar la misma construcción que fue buena en sus idiomas favoritos. Solo más tarde se descubre que la definición de variables en el bloque es mala (no hay alcance de nivel de bloque en JavaScript) y que declaraciones de funciones No siempre es la mejor opción también.

Otros consejos

No hay Modo estricto violación en su código. Si lo hubiera, recibirías un error de algún tipo.

Por JavaScript nativo, this estarán undefined en strict mode Si la función contiene tampoco se invoca:

  • Como método de un objeto
  • por Function.call o Function.apply
  • como constructor

Esa es la razón por la que Jshint se queja de ello.

Sin embargo, si la función se está utilizando como controlador de eventos para jQuery, jQuery forzará el $(this) como el objeto jQuery del DOM que dispara el evento.

Para probar esto, abra la consola de esta página y ejecute el siguiente código.

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

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

Haga clic en cualquier pregunta o respuesta de esta página y verá que el fondo se vuelve rojo.

¡Más fácil!Simplemente use EV.CurrentTarget en lugar de esto. Es lo mismo con lo que puedes probar ===

function event_handler(ev) {
    //var $el = $(this); // jshint - error
    var $el = $(ev.currentTarget); // is exactly the same as above
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top