javascriptのthisキーワードを簡単に分析します.
2918 ワード
javasriptと付き合っています.決してthisを知らないはずはない.
初めてthisに接触して、いつもそれがとても強大で神秘的だと思っています.予知できない、人知れず魔力があるらしい.
それに触れる前に、ほとんどの人はthisがこれらのoop言語の特許だと思っています.少なくとも私はそう思いました.
時間が経つにつれて、javascriptに対する更なる向上があります.thisの神秘的なベールが一歩ずつ解けていく.おしゃべりはやめて、この神秘的なベールの裏側のthisを見てみましょう.
まず、私たちはthisとは何かを知りたいです.その意味.通俗的に言うと、thisはまず対象です.次に知るべきはthisは自分がどこにいるかで決まるのではないです.
オブジェクトを呼び出して決定するのではなく、簡単に理解することができます.誰がthisを呼び出しましたか?それならthisは誰を表しますか?例えばグローバルスコープでthisを呼び出します.この時のthisはグローバル変数を表しています.
例:
thisがオブジェクトの中に現れたら、正常になります.thisはそのオブジェクトを表します.
例:
残念ですが、上記の答えは全部間違っています.とりあえず、正しい答えを急いで発表しないでください.運行中のthisが何を表しているのかを分析してみます.
o.e(fn)を実行する場合の場合、eの中のthisはoを表しています.oですのでeを呼び出しました.これは信じています.
eに入ると.fn()を実行しますこのときのfnとは、パラメータが伝達されたfnであり、関数名は、指向関数の参照のみを保存しているからである.ですから、e内部のfnは外のfnと同じです.また関数内部のthisは関数の使用者によって決定されます.だから、fn内のthisはwindowを表しています.この点は当主を信じても大丈夫です.
argments[0]()を実行すると、argments[0]は関数の最初のパラメータであり、fnに等しい.だからこの時の関数は外部のfnに等しくて、理論的にはthisもwindowに等しいべきです.
このように解釈するのは合理的なようです.正しい答えは20、20であるべきです.なぜ上の答えの中に一つもないというのが正しいですか?それは私たちが少し油断したからです.それは、アーグメンントです.
argments[0]()によると.かなりargments.0();つまり、正真がfnを呼び出すのはアーグメンントです.だから関数内部のthisはargmentsであるべきです.this.lengthはパラメータの個数、つまり1.正解は20 1.
分かりましたよね.じゃ、どのような機械が作られているか見てみます.
まず、関数が実行されたとき.彼はいずれも新しい実行環境に入ります.同じ関数を二回呼び出しても、異種または関数自体を再帰的に呼び出します.それらが入る実行環境は違います.
この実行環境に入ると、アクティブオブジェクトが作成され、実行環境に関連します.そして関数の作用ドメインチェーン,thisなどを決定した.だから、thisの値はそこに現れるものとは関係がない.逆に関数の使用者と関係があります.
だから、覚えておけばいいです.thisは関数を呼び出す対象です.thisはthisに関する問題に悩まされないようにします.
初めてthisに接触して、いつもそれがとても強大で神秘的だと思っています.予知できない、人知れず魔力があるらしい.
それに触れる前に、ほとんどの人はthisがこれらのoop言語の特許だと思っています.少なくとも私はそう思いました.
時間が経つにつれて、javascriptに対する更なる向上があります.thisの神秘的なベールが一歩ずつ解けていく.おしゃべりはやめて、この神秘的なベールの裏側のthisを見てみましょう.
まず、私たちはthisとは何かを知りたいです.その意味.通俗的に言うと、thisはまず対象です.次に知るべきはthisは自分がどこにいるかで決まるのではないです.
オブジェクトを呼び出して決定するのではなく、簡単に理解することができます.誰がthisを呼び出しましたか?それならthisは誰を表しますか?例えばグローバルスコープでthisを呼び出します.この時のthisはグローバル変数を表しています.
例:
console.log(this === window)
上述のように、グローバルスコープで分析します.thisはグローバル変数を表します.つまりwindowです.それは事実ですか?上のコードを実行して、trueを出力します.thisを証明するのはwindowです.thisがオブジェクトの中に現れたら、正常になります.thisはそのオブジェクトを表します.
例:
var obj = {
fn:function(){
console.log(this === obj);
}
}
obj.fn();//true
この二つの点が分かりました.thisの真相はもう明らかになったようです.複雑な点の例を見てみましょう.多くの人が間違いをすると信じています.同時にこれも経典的な面接問題です.var length = 20;
function fn(){
console.log(this.length);
}
var o = {
length:10,
e:function (fn){
fn();
arguments[0]();
}
}
o.e(fn);
多くの靴があると信じています.麺が20、20を出力すると思います.一部の人は10,10と思っています.又は20、10、20;残念ですが、上記の答えは全部間違っています.とりあえず、正しい答えを急いで発表しないでください.運行中のthisが何を表しているのかを分析してみます.
o.e(fn)を実行する場合の場合、eの中のthisはoを表しています.oですのでeを呼び出しました.これは信じています.
eに入ると.fn()を実行しますこのときのfnとは、パラメータが伝達されたfnであり、関数名は、指向関数の参照のみを保存しているからである.ですから、e内部のfnは外のfnと同じです.また関数内部のthisは関数の使用者によって決定されます.だから、fn内のthisはwindowを表しています.この点は当主を信じても大丈夫です.
argments[0]()を実行すると、argments[0]は関数の最初のパラメータであり、fnに等しい.だからこの時の関数は外部のfnに等しくて、理論的にはthisもwindowに等しいべきです.
このように解釈するのは合理的なようです.正しい答えは20、20であるべきです.なぜ上の答えの中に一つもないというのが正しいですか?それは私たちが少し油断したからです.それは、アーグメンントです.
argments[0]()によると.かなりargments.0();つまり、正真がfnを呼び出すのはアーグメンントです.だから関数内部のthisはargmentsであるべきです.this.lengthはパラメータの個数、つまり1.正解は20 1.
分かりましたよね.じゃ、どのような機械が作られているか見てみます.
まず、関数が実行されたとき.彼はいずれも新しい実行環境に入ります.同じ関数を二回呼び出しても、異種または関数自体を再帰的に呼び出します.それらが入る実行環境は違います.
この実行環境に入ると、アクティブオブジェクトが作成され、実行環境に関連します.そして関数の作用ドメインチェーン,thisなどを決定した.だから、thisの値はそこに現れるものとは関係がない.逆に関数の使用者と関係があります.
だから、覚えておけばいいです.thisは関数を呼び出す対象です.thisはthisに関する問題に悩まされないようにします.