Javascript / jsLint: чем заменить jQuery (this) при использовании «use strict»; - PullRequest
23 голосов
/ 04 сентября 2011

Когда я проверяю следующий код с помощью 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, символ 56: Строгое нарушение.

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

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

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

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

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

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

Ответы [ 4 ]

20 голосов
/ 04 сентября 2011

Я думаю, проблема в том, что вы используете 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 не приводится к объекту. это значение null или undefined не преобразуется в глобальный объект, а примитивные значения не преобразуются в объекты-оболочки.Значение this , переданное с помощью вызова функции (включая вызовы, сделанные с использованием Function.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».Это реальная проблема, которую вы должны учитывать при разработке своих программ на JavaScript.

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

2 голосов
/ 04 сентября 2011

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

1 голос
/ 25 февраля 2017

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

function event_handler(ev) {
    //var $el = $(this); // jshint - error
    var $el = $(ev.currentTarget); // is exactly the same as above
}
1 голос
/ 10 января 2017

По нативному 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);
})();

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

...