[解決済み】関数内で "this "キーワードはどのように機能するのでしょうか?
質問
JavaScriptで面白い場面に出くわしました。 オブジェクトリテラル記法でいくつかのオブジェクトを定義するメソッドを持つクラスがあります。 それらのオブジェクトの内部では
this
ポインタが使用されています。 プログラムの動作から推論すると
this
ポインターは、メソッドが呼び出されたクラスを参照しており、リテラルによって作成されるオブジェクトを参照しているわけではありません。
これは、私が期待する動作ではありますが、恣意的に思えます。 これは定義された動作なのでしょうか? クロスブラウザでも大丈夫なのでしょうか? なぜこのような動作になるのか、仕様に書かれている以上の理由があるのでしょうか?(たとえば、より広範な設計上の決定や哲学の結果なのでしょうか?) パースされたコードの例。
// inside class definition, itself an object literal, we have this function:
onRender: function() {
this.menuItems = this.menuItems.concat([
{
text: 'Group by Module',
rptletdiv: this
},
{
text: 'Group by Status',
rptletdiv: this
}]);
// etc
}
解決方法は?
私の別の記事からの共食いですが、ここにあなたが今まで知りたかった以上のことがあります。 これ .
始める前に、Javascriptについて覚えておくべき、そして意味がわからないときに自分に言い聞かせるべき、最も重要なことを説明します。 Javascriptにはクラスがありません(ES6
class
は
構文糖
). もし何かがクラスのように見えたら、それは巧妙なトリックです。Javascriptには
オブジェクト
と
機能
. (100%正確ではありません。関数は単なるオブジェクトですが、別物として考えることが役に立つこともあります)
その これ 変数は関数に付属しています。 関数を呼び出すと必ず これ は、関数を呼び出す方法に応じて、ある特定の値が与えられます。 これを呼び出しパターンと呼ぶことが多い。
javascriptで関数を呼び出すには、4つの方法があります。 関数を呼び出すには メソッド として、または 関数 として コンストラクタ で、そして 適用 .
メソッドとして
メソッドは、オブジェクトに付属する関数です。
var foo = {};
foo.someMethod = function(){
alert(this);
}
メソッドとして呼び出された場合。 これ は、その関数/メソッドが属するオブジェクトに束縛されます。 この例では、fooにバインドされます。
関数として
単体で機能を持つ場合は これ 変数はグローバルオブジェクトにバインドされ、ほとんどの場合、そのグローバルオブジェクトは ウィンドウ オブジェクトを使用します。
var foo = function(){
alert(this);
}
foo();
これは、あなたがつまづいている原因かもしれません。 しかし、悪く思わないでください。 多くの人が、これは設計上の悪い判断だと考えています。 コールバックはメソッドとしてではなく関数として呼び出されるため、一貫性のない動作に見えるのはそのためです。
多くの人がこの問題を回避するために、えーと、こんなことをやっています。
var foo = {};
foo.someMethod = function (){
var that=this;
function bar(){
alert(that);
}
}
変数を定義します。 その を指し示す。 これ . クロージャは(それ自体がトピックである)、次のように保持します。 その そのため、コールバックとしてbarを呼び出すと、まだ参照が残っています。
注
use strict
モードとなります。
this
はグローバルに束縛されない。(それは
undefined
).
コンストラクタとして
また、コンストラクタとして関数を呼び出すこともできます。 使用している命名規則 (TestObject) に基づいて、これもまた あなたがやっていることが、あなたをつまずかせる原因かもしれません。 .
コンストラクタとして関数を呼び出すには、new キーワードを使用します。
function Foo(){
this.confusing = 'hell yeah';
}
var myObject = new Foo();
コンストラクタとして呼び出されると、新しい Object が作成されます。 これ はそのオブジェクトにバインドされます。 繰り返しますが、インナー関数があり、それがコールバックとして使われている場合、関数として呼び出すことになります。 これ はグローバルオブジェクトにバインドされます。 var that = this のトリック/パターンを使ってください。
コンストラクタ/new キーワードは、Java/伝統的な OOP プログラマがクラスに似たものを作成する方法として投げられた骨だと考える人もいます。
Applyメソッドで
最後に、すべての関数には "apply" という名前のメソッドがあります(そう、関数はJavascriptのオブジェクトなのです)。 Applyを使うと これ になります。また、引数の配列を渡すこともできます。 以下は役に立たない例です。
function foo(a,b){
alert(a);
alert(b);
alert(this);
}
var args = ['ah','be'];
foo.apply('omg',args);
関連
-
[解決済み】Angular JS Uncaught Error。[インジェクター:モジュラー]。
-
[解決済み】Reactのeslintエラーはpropsの検証で見つからない
-
[解決済み】DOMException: サポートされているソースが見つからなかったため、読み込みに失敗しました。
-
[解決済み] Access-Control-Allow-Originヘッダーはどのように機能するのですか?
-
[解決済み] HTML5のlocalStorageにオブジェクトを格納する方法は?
-
[解決済み] セレクタの子を取得する方法は?
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み] Facebookがブラウザに統合されたDeveloper Toolsを無効にする方法を教えてください。
-
[解決済み] コールバック内で正しい `this` にアクセスする方法
-
[解決済み】関数の前のエクスクラメーションマークは何をするのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】React Js: Uncaught (in promise) SyntaxError: 位置 0 の JSON で予期しないトークン < が発生しました。
-
[解決済み】Failed to load resource: net::ERR_FILE_NOT_FOUND loading json.js
-
[解決済み】Uncaught TypeError: nullのプロパティ'value'を読み取ることができない
-
[解決済み】JavaScriptのgetElementByNameが機能しない
-
[解決済み】コンソールがUnterminated JSX contentsエラーを投げる【終了しました
-
[解決済み】JavaScript ランタイムエラー:'$'が未定義です。
-
[解決済み】XMLパースエラー:ルート要素が見つからない コンソールの場所 FF
-
[解決済み】FirefoxでGoogle Maps V3をリモートで使用すると「googleが定義されていません」と表示される。
-
[解決済み】'useState' が定義されていない no-undef React
-
[解決済み】Uncaught TypeError: 未定義のプロパティ 'msie' を読み取れない - jQuery tools