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)
}
No.1
- 回答日時:
F2はコンストラクタ、F1は普通の関数という違いがあります。
それによって、thisの参照先が変わります。
・コンストラクタではthisはインスタンスへの参照、
・普通の関数ではthisはwindowへの参照
通常は、普通の関数でthisを使うことはないと思います。
この回答への補足
回答、ありがとうございます。
F1, F2, どちらの関数も同様に this.obj1= obj1; の形式の文を持っているのに、
F2 だけがコンストラクタになるのがいまいち理解できません。
このあたりをもう少し解説していただけると助かります。
※ JavaScriptは最近始めて、C++との違いに戸惑っております。
よろしく、お願いします。
No.2
- 回答日時:
もっと簡単に考えればいいんじゃないかなと。
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
No.3ベストアンサー
- 回答日時:
原則として、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 の定義は、どこにもありません。
詳しい説明をありがとうございます。
おかげさまで、理解を進めることができました。
JavaScriptはJavaとかC++の単なるSubSetみたいに思っていたのですが、
そうではない独特な仕組みを持っていることが分かったとともに
とても興味がわいてきました。今後も勉強していきたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 数学 数学 解答三行目の →OC=−(→OA+→OB) −(→OC)=→OA+→OB にして計算していって 2 2023/08/09 13:48
- 数学 数学(三角比) 四面体OABCについて、「OA=1」「OB=√2」「OC=2」「OA⊥OB」「OB⊥ 1 2023/02/13 21:22
- 数学 数学(ベクトル) ベクトルは「OA,OB」「a,b」と表しますが 「原点が同じOだから、OA=a,O 3 2023/04/09 21:09
- 数学 このようなベクトルOPをOA OBで表す問題でよく、図のようにs:1-sで置くと思うんですけど、AP 4 2022/08/08 10:25
- 数学 ベクトルと図形の問題で、 △OABの、辺OA、OB上にそれぞれ内分点P、Qがあって(比は分かっている 2 2022/08/01 10:55
- 数学 数学の質問です。 △OAB の辺 OA を3:1 に外分する点をP, 辺 OB を 2:1 に内分す 1 2023/07/03 14:06
- サッカー・フットサル Jリーグの話 3 2023/01/01 02:41
- サッカー・フットサル Jリーグの話 2 2022/12/15 16:11
- ゴルフ ゴルフ初心者です。基本的なゴルフの事でなのですがプレイング4が無いホールのティーショットでOBを出し 4 2023/08/07 23:25
- サッカー・フットサル Jリーグの話 1 2022/12/02 23:19
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
多人数のじゃんけんプログラム
-
COMコンポーネントって何?
-
VBA 同じ名前のオブジェクトを...
-
ワイルドカード<?>と型パラメー...
-
VBAのWindowオブジェクトとWork...
-
文字列でクラス型名を取得したい
-
Listに格納されているオブジェ...
-
オブジェクト名をforループ内で...
-
ArrayLsitのデータ取得
-
LISTBOXの内容が更新されま...
-
Visual Studioでのbmpファイル...
-
パワーポイントのVBAでテキスト...
-
.getElementById()のエラーにつ...
-
C#でフォームのオブジェクト名...
-
Listに格納されたオブジェクト...
-
Vbで通常使用するプリンターを...
-
Excelで =EMBED("Acrobat Docu...
-
VBAからノーツを起動
-
Java認定試験3級の問題です。 ...
-
BufferedWriterのcloseメソッド
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
パワーポイントのVBAでテキスト...
-
Excelで =EMBED("Acrobat Docu...
-
EXCEL VBAにて動的にCheckBOXを...
-
ワイルドカード<?>と型パラメー...
-
C#でフォームのオブジェクト名...
-
VBAのWindowオブジェクトとWork...
-
vb.net オブジェクト指向につい...
-
COMコンポーネントって何?
-
オブジェクトレベルとメタレベル
-
ビジュアルC++でボタンの有...
-
時間帯判定をする。
-
LISTBOXの内容が更新されま...
-
VBA 同じ名前のオブジェクトを...
-
オブジェクト名をforループ内で...
-
Object型からDouble型へのキャスト
-
ADO オブジェクトの渡し方
-
bmp画像をjpegやpng画像に圧縮...
-
Vbで通常使用するプリンターを...
-
戻り値がクラスオブジェクト
-
VBAでvlookup関数から、別シー...
おすすめ情報