次のコードでthis
を使用すると、JSLintが驚く理由を理解するのに苦労します。
function testConstr (x) {
'use strict';
this.joker = "Whyyy sooo seriousss?";
this.x = x;
}
両方のプロパティの割り当てについて、JSLintは次のように述べています。予期しない「this」コードを修正するにはどうすればよいですか?
あなたのコードmight完全に正しい(testConstr
の呼び出し方によっては問題になるかもしれません)。
私の提案は:JSLintに黙らせる
または、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
の使用を失い、オブジェクトのすべてのメソッドを含める必要がありますPeep
sの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
を変更するのは本当に悪いニュースです。 「一部のPerson
sには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からの を参照してください。
(通常、コンストラクターは値を返しませんが、通常のオブジェクト作成プロセスをオーバーライドする場合は、値を返すことを選択できます。)
'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;
}());
厳格モードでは、this
参照はundefined
に設定されます。
したがって、両方のステートメントがundefined
オブジェクトのプロパティを読み取り、例外が発生します。
コードを修正するにはどうすればよいですか?
これらの行を両方とも削除します。
UPD:私が上で述べているのは、JSLintがあなたのコードをどのように扱うかであり、私がそれを行う方法ではありません。
JSLintの発言:予期しない「これ」。コードを修正するにはどうすればよいですか?
コードを修正する必要はありません。
ヘルプページのJSLint のセクション/*jslint*/
ディレクティブ、「Tolerate this
」オプションが利用可能なテーブルに追加されましたオプション:
+---------------+------+---------------------------------+
| Tolerate this | this | true if this should be allowed. |
+---------------+------+---------------------------------+
したがって、this
の使用に関する苦情を抑えるには、最初のステートメントの前にソースファイルに次のディレクティブを配置します。
/*jslint
this
*/
(他の/*jslint*/
オプションは、オプションの間にコンマを挿入することにより、this
の後に続けることができます。 JSLintヘルプページを参照してください。)
@ Oriol による回答も参照して、 "Tolerate this
"オプションを有効にしてください。 JSLintのユーザーインターフェイス。
私が知っている古い質問ですが、それが誰かを助ける場合、私はダグラス・クロックフォードによる talk を見ていました。彼は、攻撃者が関数を使用し、「this」キーワードを使用してグローバルスコープにアクセスします。
彼はまた、Object.createを使用しないことも意味していると語っています-これは彼がこの言語を紹介するのに役立った機能です!