严格违规使用此关键字并显示模块模式

Mat*_*y F 53 javascript strict module-pattern

无法获取以下内容以传递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();
Run Code Online (Sandbox Code Playgroud)

我理解它是由this函数声明中的使用引起的,但是我读过Crockford写的东西,他说违规是为了防止全局变量污染 - 但这里唯一的全局变量就是我明确定义的变量...... myModule.其他所有东西都保存在直接的功能范围内,我应该可以用它this来引用该模块.

任何想法如何让这种模式通过?

更新:如果我使用函数表达式而不是声明,这似乎工作,即

var pubFn = function () { ...
Run Code Online (Sandbox Code Playgroud)

我不是这种格式的粉丝,更喜欢将函数名称和命名参数更接近并且声明看起来/感觉更清晰.老实说,我不明白为什么这会引发违规行为 - 在这种模式中没有理由这样做.

mar*_*ian 80

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!
}
Run Code Online (Sandbox Code Playgroud)

在每个适用的函数中指定它可能看起来很痛苦,但如果在模块函数的顶部设置选项,则可能会隐藏自己的真正严格模式违规.


Lar*_*sen 25

这里真正的问题是,如果你privFn模块上下文(从IIFE内)调用,thisundefined在严格模式下; window如果不是严格的模式.唉,如果从IIFE内部调用,该功能将失败.

这是因为当从IIFE内部调用时函数没有所有者(对象),而返回的模块对象是从IIFE上下文外部调用它们时的函数的所有者,例如this === myModule在调用时myModule.pubFn().

严格模式和JSHint/JSLint都试图帮助你,你永远不应该忽略它们产生的错误/警告,而是找出它们警告你的原因.

如果你确信百分之百privFn,pubFn等不会被任何地方,但你的模块外调用,只是把在评论/*jshint validthis: true */中生成一个警告任何功能.或者,IIFE中的一条注释将阻止JSHint在模块内的任何函数上生成此错误.


许多可能的解决方案之一

存储this(在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();
Run Code Online (Sandbox Code Playgroud)