Javascript/jsLint: что заменить jQuery (это) при использовании "use strict";

Когда я проверяю следующий код с помощью jslint, я получаю следующие ошибки.

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

Проблема с символом строки 4 29: Строгое нарушение.

 liMegaPosition = jQuery(this).position();  

Проблема с символом строки 5: строгое нарушение.

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

Проблема с символом линии 6 12: строгое нарушение.

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

Проблема с символом строки 8: Строгое нарушение.

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

Я предполагаю, что это из-за использования jQuery (это), но я не понимаю, что заменить его. Обратите внимание, что это не потому, что jQuery не объявляется глобальным.

+23
источник поделиться
4 ответа

Я думаю, проблема в том, что вы используете this не внутри метода. Следующий код

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

или этот

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

не даст вам никаких ошибок или предупреждений.

ОБНОВЛЕНО. Еще одна версия, которая очень близка к вашей оригинальной, также не содержит ошибок или предупреждений:

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

ОБНОВЛЕНО 2. Я нахожу вопрос интересным для понимания. Поэтому я просматриваю стандарт ECMAScript. Я нашел следующее в "Приложении C (информативный)" Строгий режим ECMAScript "(см. Выше в HTML-версии здесь):

Если этот оценивается в коде строгого режима, значение thisне принуждали к объекту. Значение this null или undefined не является преобразованные в глобальный объект, а примитивные значения не преобразуются для обертки объектов. Значение this передается через вызов функции (включая вызовы, выполненные с использованием функции .prototype.apply и Function.prototype.call) не принуждают переданное значение к объект (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4).

Я полагаю, что это причина ошибки JSLint.

Если вы отключите строгий режим, код не будет иметь больше ошибок:

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

ОБНОВЛЕНО 3: Похоже, что невозможность использования this в выражении функции и возможность использования this в выражении функции подозреваются многими людьми. Сегодня я получил еще один комментарий по этому поводу. Поэтому я создал очень простую демонстрацию

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

    test();
}());

Вы можете протестировать его здесь, чтобы в IE9 демонстрационное оповещение с текстом "[окно объекта]" и в текущих версиях Chrome и Firefox вы увидите "undefined".

Таким образом, проблема с использованием this в описании функции не является "jslint thing". Это настоящая проблема, которую вы должны учитывать при разработке ваших программ JavaScript.

Я лично предпочитаю использовать выражение функции и почти никогда не использую больше операторов функций. Я думаю, что люди, которые приходят с других языков программирования (например, я тоже), стараются вначале использовать ту же самую конструкцию, которая была хороша на ваших любимых языках. Только позже выясняется, что определение переменных в блоке плохое (в JavaScript нет области уровня блока), и что операторы функций не всегда являются лучшим выбором.

+20
источник

В коде отсутствует строгое нарушение режима. Если бы это было, вы получили бы какую-то ошибку.

+2
источник

С помощью встроенного javascript this будет undefined в strict mode, если функция содержит его, также не вызывается:

  • как метод объекта
  • Function.call или Function.apply
  • как конструктор

В этой причине jshint жалуется на это.

Однако, если функция используется как обработчик событий для jQuery, jQuery заставит $(this) как объект jQuery DOM, который вызывает событие.

Чтобы это доказать, откройте консоль этой страницы и запустите следующий код.

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

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

Нажмите любой вопрос или ответ на эту страницу, и вы увидите, что фон становится красным.

+1
источник

Намного проще! Вместо этого используйте ev.currentTarget. Это то же самое, что вы можете проверить с помощью ===

function event_handler(ev) {
    //var $el = $(this); // jshint - error
    var $el = $(ev.currentTarget); // is exactly the same as above
}
+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос