私はJavaScriptが初めてです。私が実際に行った限りでは、既存のコードを微調整し、jQueryを少し書いただけです。
現在、属性とメソッドを使用して「クラス」を作成しようとしていますが、メソッドに問題があります。私のコード:
function Request(destination, stay_open) {
this.state = "ready";
this.xhr = null;
this.destination = destination;
this.stay_open = stay_open;
this.open = function(data) {
this.xhr = $.ajax({
url: destination,
success: this.handle_response,
error: this.handle_failure,
timeout: 100000000,
data: data,
dataType: 'json',
});
};
/* snip... */
}
Request.prototype.start = function() {
if( this.stay_open == true ) {
this.open({msg: 'listen'});
} else {
}
};
//all console.log's omitted
問題は、Request.prototype.start
、this
は未定義であるため、ifステートメントはfalseと評価されます。ここで何が間違っていますか?
どのように開始関数を呼び出していますか?
これは動作するはずです(newがキーです)
_var o = new Request(destination, stay_open);
o.start();
_
Request.prototype.start()
のように直接呼び出すと、this
はグローバルコンテキスト(ブラウザーではwindow
)を参照します。
また、this
が未定義の場合、エラーになります。 if式はfalseと評価されません。
更新:this
オブジェクトは宣言に基づいて設定されるのではなく、invocationによって設定されます。つまり、関数プロパティを_x = o.start
_などの変数に割り当ててx()
を呼び出すと、start内のthis
はo
を参照しなくなります。 setTimeout
を実行すると、これが起こります。動作させるには、代わりに次のようにします:
_ var o = new Request(...);
setTimeout(function() { o.start(); }, 1000);
_
JavaScriptのOOPは少しファンキー(またはかなり)で、慣れるのに少し時間がかかります。最初に覚えておく必要があるのは、クラスがないそして、クラスの観点から考えると、あなたをつまずかせる可能性がありますコンストラクター(クラス定義に相当するJavaScript)にアタッチされたメソッドを使用するには、オブジェクトをインスタンス化する必要があります。
Ninja = function (name) {
this.name = name;
};
aNinja = new Ninja('foxy');
aNinja.name; //-> 'foxy'
enemyNinja = new Ninja('boggis');
enemyNinja.name; //=> 'boggis'
Ninja
インスタンスには同じプロパティがありますが、aNinja
はenemyNinja
のプロパティにアクセスできません。 (この部分は本当に簡単/簡単なはずです)prototype
に何かを追加し始めると、物事が少し異なります:
Ninja.prototype.jump = function () {
return this.name + ' jumped!';
};
Ninja.prototype.jump(); //-> Error.
aNinja.jump(); //-> 'foxy jumped!'
enemyNinja.jump(); //-> 'boggis jumped!'
これを直接呼び出すと、コンストラクターがインスタンス化されたときにのみthis
が正しいオブジェクト(「クラス」)を指すため、エラーがスローされます(そうでない場合はブラウザーのグローバルオブジェクトwindow
を指します)
ES2015 a.k.a ES6では、class
はfunctions
の構文糖です。
this
のコンテキストを強制的に設定する場合は、bind()
メソッドを使用できます。 @chetanが指摘したように、呼び出し時にコンテキストも設定できます!以下の例を確認してください。
_class Form extends React.Component {
constructor() {
super();
}
handleChange(e) {
switch (e.target.id) {
case 'owner':
this.setState({owner: e.target.value});
break;
default:
}
}
render() {
return (
<form onSubmit={this.handleNewCodeBlock}>
<p>Owner:</p> <input onChange={this.handleChange.bind(this)} />
</form>
);
}
}
_
ここでは、handleChange()
内のコンテキストをForm
に強制しました。