Строгое нарушение с использованием этого ключевого слова и выявление шаблона модуля



возникли проблемы с получением следующего, чтобы передать jslint / jshint

/*jshint strict: true */
var myModule = (function() {
    "use strict";

    var privVar = true,
        pubVar = false;

    function privFn() {
        return this.test; // -> Strict violation.
    }

    function pubFn() {
        this.test = 'public'; // -> Strict violation.
        privFn.call(this); // -> Strict violation.
    }

    return {
        pubVar: pubVar,
        pubFn: pubFn
    };

}());

myModule.pubFn();

Я понимаю, что это вызвано использованием this в объявлении функции, но я прочитал что - то написанное Крокфордом, и он сказал, что нарушение предназначено для предотвращения загрязнения глобальной переменной, но единственная глобальная переменная здесь-это та, которую я явно определяю... myModule. Все остальное хранится в непосредственной области функции, и я должен быть в состоянии использовать this для обозначения модуль.

любые идеи, как я могу получить этот шаблон, чтобы пройти?

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

var pubFn = function () { ...

Я не поклонник этого формата, хотя предпочитаю иметь имя функции и именованные параметры ближе, а объявление выглядит/чувствует себя чище. Я честно не понимаю, почему это бросает нарушение - нет никаких причин для этого в этом шаблоне.

157   3  

3 ответов:

JSHint имеет опции под названием validthis, где:

[...] подавляет предупреждения о возможных строгих нарушениях, когда код выполняется в строгом режиме и вы используете this в функции, не являющейся конструктором [...], когда вы уверены, что ваше использование this действует в строгом режиме.

используйте его в функции, на которую жалуется JSHint, которая в вашем случае будет выглядеть так:

function privFn() {
    /*jshint validthis: true */
    return this.test; // -> No Strict violation!
}

function pubFn() {
    /*jshint validthis: true */
    this.test = 'public'; // -> No Strict violation!
    privFn.call(this); // -> No Strict violation!
}

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

реальная проблема здесь заключается в том, что если вы называете privFn внутри контекст модуля (из IIFE),this будет undefined когда в строгого режима; window если не в строгом режиме. Увы, функция потерпит неудачу, если будет вызвана из IIFE.

это потому, что функции нет собственником (объект), когда позвонил в жизнь, в то время как возвращаемый объект модуля - это владелец функций, когда они вызываются из-за пределов контекста IIFE, например this === myModule при вызове myModule.pubFn().

оба строгий режим и JSHint/JSLint пытаются помочь вам, и вы никогда не должны просто игнорировать ошибки/предупреждения, созданные ими, но вместо этого выяснить, почему они предупреждают вас.

если вы на 100 процентов уверены в том, что privFn,pubFn и т. д. не будет вызываться нигде, кроме как за пределами вашего модуля, просто поместите комментарий /*jshint validthis: true */ в любых функциях, которые создайте предупреждение. Кроме того, один комментарий в IIFE не позволит JSHint генерировать эту ошибку для любой функции внутри модуля.


одно из многих возможных решений

сохранить объем this (in self в этом примере) для явной ссылки на модуль. Это покажет и обеспечит ваше намерение.

/*jshint strict: true */
var myModule = (function() {
    "use strict";

    var privVar = true,
        pubVar = false,
        self = this;

    function privFn() {
        return self.test;
    }

    function pubFn() {
        self.test = 'public';
        //privFn.call(this); // Will have no effect, as `privFn` does not reference `this`
        privFn();
    }

    return {
        pubVar: pubVar,
        pubFn: pubFn
    };
}());

myModule.pubFn();

к сожалению, это предполагаемая ошибка для этой установки, так как jslint/jshint не знают, что функция, объявленная в глобальном контексте, будет позже использоваться в качестве метода объекта.

    Ничего не найдено.

Добавить ответ:
Отменить.