JSHint выдает «неопределенные» предупреждения в раскрывающемся шаблоне модуля

Я получаю несколько «неопределенных» ошибок при запуске этого кода в JSHint:

MERLIN.namespace('MERLIN.http');

MERLIN.http = function ($, window) {
    'use strict';
    // import dependencies

    function request(config) {
        if (!config || typeof config !== 'object') {
            return;
        }
        // perform request
        $.ajax({
            type: config.type || 'GET',
            url: config.url,
            dataType: config.dataType,
            data: config.data || {},
            processData: config.process || false,
            beforeSend: function () {
                indicator(config.panel, config.indicator);
            },
            complete: function () {
                indicator(config.panel, config.indicator);
            },
            success: function (resp) {
                var callback = config.success || null;
                if (typeof callback !== 'function') {
                    callback = false;
                }
                if (callback) {
                    callback.apply(this, [resp]);
                }
            },
            error: function (xhr, textStatus, errorThrown) {
                httpError({
                    xhr: xhr,
                    status: textStatus,
                    error: errorThrown,
                    panel: config.panel
                });
            }
        });
    };

    function indicator(panel, type) {
        if ((!panel || typeof panel !== 'string') || (!type || typeof type !== 'string')) {
            return;
        }
        var indicatorType = (type === 'large') ? type = 'indicatorLarge' : type = 'indicatorSmall';
        return $(panel).toggleClass(indicatorType);
    };

    function httpError() {
        return this;
    };

    return {
        request: request,
        error: httpError
    };

} (jQuery, this);

Я не уверен, почему неопределенные ошибки выдаются для «индикатора» и «httpError» и почему использование «вернуть это» является потенциальным строгим нарушением. Я знаю, что могу спокойно игнорировать неопределенную ошибку, связанную с пространством имен, поскольку функция пространства имен общего назначения определена ранее в отдельном файле.

Это просто случай прагматизма против строгой проверки?

Спасибо :)


person RyanP13    schedule 18.01.2012    source источник
comment
Пожалуйста, указывайте фактические ошибки.   -  person T.J. Crowder    schedule 18.01.2012


Ответы (1)


Что касается 'indicator' is not defined. и подобных ошибок: JSHint является производным от JSLint, написанного Дугласом Крокфордом. У Крокфорда есть проблема с вызовами функций, появляющимися в исходном тексте до того, как они определены, хотя это совершенно правильный и законный код, и в нем нет никакой двусмысленности. Я на самом деле думаю, что это тот случай, когда JSLint (и JSHint, когда эта ошибка включена) активно противодействует полезности. Я хочу знать, когда что-то действительно не определено, а не когда оно не определено в соответствии с Крокфордом. -стиль-правила. (Не то, чтобы у меня было мнение.)

Вы могли бы избежать этих ошибок, переместив объявления indicator и httpError выше request, но, кроме ложных ошибок от JSHint, для этого нет причин.

Что касается ошибки return this;, я считаю, что это способ JSLint/JSHint сообщить вам, что вы возвращаете глобальный объект, потому что он ожидает, что функции, начинающиеся с буквы нижнего регистра, просто вызываются как функции, а не псевдометоды. Почему httpError возвращает this? То, как вы это называете, this будет глобальным объектом.

Таким образом, хотя в этом случае вы возвращаете глобальный объект правильно, вы также можете получить эту ошибку совершенно ложно. Например, этот код выдает такую ​​ошибку:

var Foo = (function() {
    "use strict";

    function Foo() {

    }
    function bar() {
        return this; // "ERROR: [8:16]: Strict violation."
    }
    Foo.prototype.bar = bar;

    return Foo;
})();

Какого-либо жесткого нарушения там нет. bar вернет this, который, если я правильно назову bar (например, var f = new Foo(); f.bar();), будет экземпляром объекта, созданного с помощью Foo, а не глобального объекта.

Если я изменю этот код, чтобы помочь моим инструментам помочь мне:

var Foo = (function() {
    "use strict";

    function Foo() {

    }

    Foo.prototype.bar = function() {
        return this;
    };

    return Foo;
})();

... ошибка исчезает, потому что JSLint/JSHint предполагают, что функция будет вызываться с this, установленным на что-то другое, чем глобальный объект. Но тогда мои функции анонимны, что далеко не идеально.

Но вы можете осчастливить JSLint/JSHint, начав имя функции не с буквы нижнего регистра. Например, мое обычное соглашение об именах работает:

var Foo = (function() {
    "use strict";

    function Foo() {

    }
    function Foo$bar() {
        return this;
    }
    Foo.prototype.bar = Foo$bar;

    return Foo;
})();

Никаких ошибок не генерируется. Имена Foobar, Foo_bar и $bar также работают.

person T.J. Crowder    schedule 18.01.2012