23

次のコードを 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(this) を使用しているためだと推測していますが、何に置き換えるかわかりません。これは、jQuery がグローバルとして宣言されていないためではないことに注意してください。

4

4 に答える 4

20

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");
}

エラーや警告は表示されません。

更新:元のバージョンに非常に近いもう1つのバージョンにも、エラーや警告はありません。

/*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標準を調べます。「AnnexC(参考)ECMAScriptの厳密なモード」(HTMLバージョンの詳細はこちらを参照)で次のことがわかります。

これが厳密なモードコード内で評価される場合、このはオブジェクトに強制変換されません。nullまたは未定義この値はグローバルオブジェクトに変換されず、プリミティブ値はラッパーオブジェクトに変換されません。関数呼び出し(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での使用の不可能性と関数式での使用の可能性は、多くの人にとって疑わしいようです。今日、私はこれについてもう1つのコメントを受け取りました。だから私は非常に簡単なデモを作成しましたthis

/*jslint devel: true */
(function () {
    'use strict';
    function test() {
        alert(this);
    }

    test();
}());

ここでテストできます。IE9では「[オブジェクトウィンドウ]」というテキストでアラートが表示され、現在のバージョンのChromeとFirefoxでは「未定義」と表示されます。

したがって、thisin関数ステートメントの使用に関する問題は「jslintのこと」ではありません。これは、JavaScriptプログラムの開発中に考慮すべき実際の問題です。

私は個人的に関数式を使用することを好み、関数ステートメントをこれ以上使用することはほとんどありません。他のプログラム言語(私のように)から来た人々は、最初はあなたの好きな言語で良かった同じ構造を使おうとしていると思います。ブロック内の変数の定義が正しくなく(JavaScriptにはブロックレベルのスコープがない)、関数ステートメントも常に最良の選択であるとは限らないことが後でわかります。

于 2011-09-04T16:32:27.583 に答える
2

コードに厳密なモード違反はありません。あった場合は、ある種のエラーが発生します。

于 2011-09-04T15:00:50.740 に答える
1

ネイティブの JavaScript では、関数に含まれている場合は呼び出されthisません。undefinedstrict mode

  • オブジェクトのメソッドとして
  • Function.callまたはによってFunction.apply
  • コンストラクタとして

それが jshint が不満を言っている理由です。

ただし、関数が jQuery のイベント ハンドラーとして使用されている場合、jQuery は$(this)イベントを発生させる DOM の jQuery オブジェクトとして を強制します。

これを証明するには、このページのコンソールを開き、次のコードを実行します。

(function(){
    "use strict";
    function event_handler() {
        $(this).css('background','red');
    }

    $('#content').on('click', 'table', event_handler);
})();

このページの質問または回答をクリックすると、背景が赤くなります。

于 2017-01-10T13:33:35.223 に答える