web-dev-qa-db-ja.com

JSLintエラー:予期しない「this」

次のコードでthisを使用すると、JSLintが驚く理由を理解するのに苦労します。

function testConstr (x) {
    'use strict';
    this.joker = "Whyyy sooo seriousss?";
    this.x = x;
}

両方のプロパティの割り当てについて、JSLintは次のように述べています。予期しない「this」コードを修正するにはどうすればよいですか?

40
jdw

あなたのコードmight完全に正しい(testConstrの呼び出し方によっては問題になるかもしれません)。

私の提案は:JSLintに黙らせる

enter image description here

または、JSLintをまったく使用しないでください。

30
Oriol

つまり、JSLintは自動的にコンストラクターパターンを使用することを期待しませんか?

あなたが知っている、私はあなたが正しいと思う。あなたの質問は私を悩ませ、私は CrockfordのJSLintディスカッショングループ および 質問 にサインアップしました。彼は答えましたが、以下に示す解決策を無視しました、私はthinkはそれが大丈夫であることを意味します、JSLintが何かが集まる場合に文句を言わないのと同じように。

(私はまだ更新された良い部品を待っています。)

それはさておき、ここでOO Beta JSLintを通過するJavaScript(とにかく今日)について行うことをお勧めします。

MDNのページ「 オブジェクト指向プログラミング入門 」の例を書き換えます。これは、それ自体thisを自由に使用します。

thisを使用

上記のリンクされたセクションの元のunlintedMDNの例を次に示します。

_var Person = function (firstName) {
  this.firstName = firstName;
};

Person.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.firstName);
};

var person1 = new Person("Alice");
var person2 = new Person("Bob");

// call the Person sayHello method.
person1.sayHello(); // logs "Hello, I'm Alice"
person2.sayHello(); // logs "Hello, I'm Bob"
_

それは、私たちが知っていて愛している慣習に従っています。

thisなし

そのパターンに従わない「コンストラクタ」を作成する方法を見つけるのは非常に簡単ですが、何かを逃していない場合はprototypeの使用を失い、オブジェクトのすべてのメソッドを含める必要がありますPeepsのallを共有するコンストラクタ。

_/*jslint white:true, devel:true */
var Peep = function(firstName) {
    "use strict";
    var peep = {};
    peep.firstName = firstName;

    peep.innerSayHello = function() {
        console.log("Hello, I'm " + peep.firstName + ".");
    };

    return peep;
};

var peep1 = new Peep("Bob");
var peep2 = new Peep("Doug");

peep1.innerSayHello();
peep2.innerSayHello();
_

そのため、リンタブルな代替手段があります。それは、_return peep;_とメソッドの内部定義を除いて、JavaScriptがあなたが遭遇するかもしれない多くのオブジェクト指向言語のように振る舞います。少なくともwrongではありません。

prototypeにアクセスできないことは恐ろしいことではありません。コードがスパゲッティに行くので、コンストラクターのすぐそばではない場所でprototypeを変更するのは本当に悪いニュースです。 「一部のPersonsにはsayGoodbye()がありますが、一部はそうではありません。構築時にプロトタイプを修正したかどうかによって異なります。 " それはひどい。したがって、この代替規則には利点があります。

もちろん、後でPeepの単一のインスタンス化に関数を追加できますが、firstNameを使用せずにthisにアクセスする方法がわかりません。彼は、建設後にオブジェクトの変更を停止することを望んでいます。

_person1.sayGoodbye = function (other) { 
    console.log("Goodbye, " + other + "."); 
};
_

(つまり、モンキーパッチPeepを使用してプロセスの途中で変更することもできますが、それは恐ろしく馬鹿げたプログラミングです。通常。

継承(thisなし)

そして、継承は簡単だと思います。

_var PeepWithGoodbye = function (firstName) {
    "use strict";
    var peepWithGoodbye = new Peep(firstName);

    peepWithGoodbye.innerSayGoodbye = function (otherPeep) {
        if (undefined === otherPeep) {
            otherPeep = { firstName: "you" };
        }
        console.log("This is " + firstName 
            + " saying goodbye to " + otherPeep.firstName + ".");
    };

    return peepWithGoodbye;
};

var pwg1 = new PeepWithGoodbye("Fred");
pwg1.innerSayHello();           // Hello, I'm Fred.
pwg1.innerSayGoodbye(peep1);    // This is Fred saying goodbye to Bob.
pwg1.innerSayGoodbye();         // This is Fred saying goodbye to you.
_

EDIT:参照 この回答 後に質問者が作成したCrockfordの推奨手段OO = javascript。Q&Aを削除してAをここに移動するようにその人を説得しようとしています。もしそうでない場合は、おそらく彼のものとコミュニティWikiをここに追加します。


EDIT:これはMDNからの を参照してください。

(通常、コンストラクターは値を返しませんが、通常のオブジェクト作成プロセスをオーバーライドする場合は、値を返すことを選択できます。)

28
ruffin
'use strict';

var SudoConstructor = (function () {

    /* We need bind, < IE9 needs a (tiny) polyfill */

    function protoEsqDeclare(sudoThis) {
        return sudoThis;
    }

    function protoEsqSet(sudoThis, newValA, newValB) {
        sudoThis.valA = newValA;
        sudoThis.valB = newValB;
    }

    function instanceCreator(valA, valB) {
        var sudoThis = {
            valA: valA,
            valB: valB
        };

        return {
            declare: protoEsqDeclare.bind(null, sudoThis),
            set: protoEsqSet.bind(null, sudoThis)
        };

    }

    return instanceCreator;

}());
3
Lee

厳格モードでは、this参照はundefinedに設定されます。

したがって、両方のステートメントがundefinedオブジェクトのプロパティを読み取り、例外が発生します。

コードを修正するにはどうすればよいですか?

これらの行を両方とも削除します。

UPD:私が上で述べているのは、JSLintがあなたのコードをどのように扱うかであり、私がそれを行う方法ではありません。

2
zerkms

JSLintの発言:予期しない「これ」。コードを修正するにはどうすればよいですか?

コードを修正する必要はありません。

ヘルプページのJSLint のセクション/*jslint*/ディレクティブ、「Tolerate this」オプションが利用可能なテーブルに追加されましたオプション:

+---------------+------+---------------------------------+
| Tolerate this | this | true if this should be allowed. |
+---------------+------+---------------------------------+

したがって、thisの使用に関する苦情を抑えるには、最初のステートメントの前にソースファイルに次のディレクティブを配置します。

/*jslint
    this
*/

(他の/*jslint*/オプションは、オプションの間にコンマを挿入することにより、thisの後に続けることができます。 JSLintヘルプページを参照してください。)

@ Oriol による回答も参照して、 "Tolerate this"オプションを有効にしてください。 JSLintのユーザーインターフェイス。

1
DavidRR

私が知っている古い質問ですが、それが誰かを助ける場合、私はダグラス・クロックフォードによる talk を見ていました。彼は、攻撃者が関数を使用し、「this」キーワードを使用してグローバルスコープにアクセスします。

彼はまた、Object.createを使用しないことも意味していると語っています-これは彼がこの言語を紹介するのに役立った機能です!

0
leon segal