53

以下を取得して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 () { ...

私はこのフォーマットのファンではありません. 正直なところ、これが違反をスローしている理由がわかりません。このパターンには理由がありません。

4

3 に答える 3

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!
}

それが適用される各関数でそれを指定しなければならないのは面倒に思えるかもしれませんが、モジュール関数の一番上にオプションを設定すると、真の厳密モード違反を自分自身から隠すことができます。

于 2012-09-11T18:05:39.267 に答える
25

ここでの本当の問題はprivFnモジュール コンテキスト内から ( IIFE内から)呼び出した場合、strict モードの場合にthisなることです。厳密モードでない場合。残念ながら、IIFE 内から呼び出された場合、関数は失敗します。undefinedwindow

これは、関数がIIFE 内から呼び出された場合は所有者(オブジェクト) を持たないためです。一方、返されたモジュール オブジェクトは、IIFE コンテキストの外部から呼び出された場合 (たとえばthis === myModuleを呼び出した場合) には関数の所有者になりますmyModule.pubFn()

厳密モードと JSHint/JSLint の両方があなたを助けようとしており、それらによって生成されたエラー/警告を無視するのではなく、警告の理由を理解する必要があります。

privFnpubFnなどがモジュールの外部以外では呼び出されないことが 100% 確実な場合は/*jshint validthis: true */、警告を生成する関数にコメントを入れてください。または、IIFE 内の 1 つのコメントにより、JSHint がモジュール内の関数でこのエラーを生成するのを防ぐことができます。


多くの可能な解決策の1つ

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();
于 2014-01-29T07:40:13.203 に答える
4

残念ながら、jslint/jshint はグローバル コンテキストで宣言された関数が後でオブジェクト メソッドとして使用されることを認識していないため、これはこのセットアップの意図したエラーです。

于 2011-06-24T01:05:40.983 に答える