2パス目はともかく、1パス目の関数が複数設置できる理由、用途はやや不明だが、長いプログラムの場合、最近の関数を信用せよということなのかも知れない。
そうは言っても、this.foo=function() { } の呼び出しが随分前にあると、これに打ち消される危険はある。また、かなり後の方にある function foo() { } のような関数にも注意しなければならない。
このことから、地の文に何でも書くのは、見つけにくいバグの原因になる危険があるかも。
ただし、このどちらの現象も、ファイルを分けた場合には起こらないようだ。
ということは、1パス2パスはファイル別に連続して行われるのかも。
手近、と言うか、同じファイル内に呼び出される関数がない場合、先のファイルで定義される関数、下の場合で言うと this.A=function()
は利用されるが、後から定義される function B() が同ファイル上にはない場合、視野外のため、エラーになる。
次に関数内の中のことだが、(new で呼び出していない)関数の中では、this は window である。
しかしこれは、this が window だというだけのことで、何もついていない変数や、 function foo() { } 、また、foo=function() { }
といった関数も this や window がついたものと同じというわけではない。
それらはあくまでローカルな変数、関数だ。new で呼び出した場合にはまた違う話になるので、一度整理しておく方が良い。
地の文: window = this = [Local]
new しない function の中: window = this ≠ [Local]
new した function の中: window ≠ this(= object) ≠ [Local]
ここで「new しない function」と言うのは、new した function の中に入れ子になって最内側で new しないものを含む。
また、このローカル変数だが、該当のものがなければ、外側のものが順次検索されるのは先の頁で static binding として説明した通りだ。これは次の例により明らかだ。
new した場合にも同じであることを確かめておこう。
new する、しないに拘わらず、関数の内側では、function foo() { } と foo=function() { } とは実行される限りは同じもの、ただし、「登録」の順序が変わる。
new しない場合において、this.foo=function() { } はグローバルな関数となるので、先の2つとは別物、window.*** は this.*** と同じだ。これは次の例に示される。
先ほどの整理をもう一度見て頂こう。
地の文: window = this = [Local]
new しない function の中: window = this ≠ [Local]
new した function の中: window ≠ this(= object) ≠ [Local]
new した場合には、object が作られ、これが this になるので、window との不一致が生じる。これはまあ良いとして、object に属する変数、関数は、ローカルなものとはまた別のものとなる。
これがかなりわかりにくく、実務の上でも混乱し易い点だ。new した関数の中では、window、this(=object)、ローカル と、都合3種類の同名の関数が並立する可能性がある。
new した関数はオブジェクトとして保存でき、その中の変数は保存されている。これはローカルな変数も同様(前編からの修正です)であり、内部の関数を通じて値を参照できる。