アプリ版:「スタンプのみでお礼する」機能のリリースについて

JavaScriptのグローバル変数
次のプログラムで、(1)は p.obj1 = 32 と表示されるのに、
(2)はエラーになります。pはグローバル変数的にアクセスできる
のに、なぜobj1がアクセスできないのかが分かりません。
詳しい方の解説をお願いします。

// test.js
main();
function main()
{
F2(new F1(32, 100));
alert("p.obj1 = "+ p.obj1); // (1)
alert("obj1 = "+ obj1); // (2)
}

function F1(obj1, obj2) {
this.obj1= obj1;
this.obj2= obj2;
}

function F2(p)
{
this.p =p;
return this.p;
}

function alert(message) {
WScript.Echo(message)
}

「JavaScriptのグローバル変数」の質問画像

A 回答 (3件)

F2はコンストラクタ、F1は普通の関数という違いがあります。


それによって、thisの参照先が変わります。

・コンストラクタではthisはインスタンスへの参照、
・普通の関数ではthisはwindowへの参照


通常は、普通の関数でthisを使うことはないと思います。

この回答への補足

回答、ありがとうございます。
F1, F2, どちらの関数も同様に this.obj1= obj1; の形式の文を持っているのに、
F2 だけがコンストラクタになるのがいまいち理解できません。
このあたりをもう少し解説していただけると助かります。
※ JavaScriptは最近始めて、C++との違いに戸惑っております。
よろしく、お願いします。

補足日時:2010/05/03 17:51
    • good
    • 0

もっと簡単に考えればいいんじゃないかなと。



function F1(obj1, obj2) {
this.obj1= obj1;
this.obj2= obj2;
}
var p = new F1(32, 100);
alert("p.obj1 = "+ p.obj1); // this == p なので参照できる
alert("obj1 = "+ obj1); // this == window ではないので参照できない

プロトタイプ(prototype)によるJavaScriptのオブジェクト指向:CodeZine
http://codezine.jp/article/detail/222
    • good
    • 0
この回答へのお礼

回答、ありがとうございます。
参考にさせていただきます。

お礼日時:2010/05/06 23:25

原則として、JavaScript の関数は全てコンストラクタです(逆はホスト依存)。

関数として振る舞うか、コンストラクタとして振る舞うかは、単純に new 演算子の有無で決まります。

・new がなくカッコ (..) があれば関数として call します。

・new があればコンストラクタになります。このとき、まずコンストラクタの prototype にセットされたオブジェクトをプロトタイプとする新規オブジェクトを生成します。次に、その新規オブジェクトを this 値としてコンストラクタに引数を渡します。最後に、コンストラクタの戻り値がオブジェクトならそれを、オブジェクト以外なら新規オブジェクトを返します。

最後の文はややこしいですが、要はコンストラクタが新規オブジェクト以外を返しうる、ということです。いろいろ実験して下さい。なお、関数として呼び出す場合は func() のように (..) で引数リストを渡さねばなりませんが、コンストラクタとして呼び出す場合は new Constr のように (..) がなくても構いません。

以上を踏まえて No.0 を見ます。なお、説明のためオブジェクト o を導入します。

・new F1(32, 100) は、まず o = new F1 のように F1.prototype をプロトタイプとするオブジェクト o を生成し、次に F1.call(o, 32, 100) のように o を this 値として F1 を呼び出します。したがって、o.obj1、o.obj2 が定義され、かつ、F1 の戻り値が undefined なので o をそのまま返します。

・F2(o) は関数として呼び出されます。この場合、F2 内の this 値はグローバルオブジェクト(WSH なら名前なし)ですから、this.p はいわゆるグローバル変数 p となります。これは o にセットされます。F2 の戻り値は this.p すなわち o ですが、call 元で再利用はしていません。

ゆえに、グローバル変数 p が参照する o のプロパティ obj1 にはアクセス可能です。しかし、グローバル変数 obj1 の定義は、どこにもありません。
    • good
    • 0
この回答へのお礼

詳しい説明をありがとうございます。
おかげさまで、理解を進めることができました。
JavaScriptはJavaとかC++の単なるSubSetみたいに思っていたのですが、
そうではない独特な仕組みを持っていることが分かったとともに
とても興味がわいてきました。今後も勉強していきたいと思います。

お礼日時:2010/05/06 23:22

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!