こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

FlashActionScriptバイブルを読破された方に質問です!2

「引数」で困っております。
本書のp305ページの「theObject」と「this」が私を混乱させます。

p305のスクリプト(その1)

this.stop();
function dropYou(theObject){
this.gotoAndStop("open");
theObject.dropped();
}

※このスクリプトには「theObject」が2つ出てきます。引数指定の()内に一つ目のtheObjectは登場します。もう一つは、droppedメソッドの前に登場します。この「theObject」は2つともが同じキーワードであるならば、例えば「obje」でも「book」でも、スクリプトは正常に動作するようです。
ですが、「this」と入れるとさすがにまずいようで、なぜなら、
theObject.dropped();
が、
this.dropped();
になってしまい、オブジェクト参照そのものがこのMCに向けられてしまうからのようです。
しかし、なぜtheObjectがdropped()メソッドのオブジェクト参照として利用することができるのでしょうか?theObjectという名のインスタンスが存在しないので???です。


p305のスクリプト(その2)

on (release) {
this.stopDrag();
_alpha = 100;
eval(_droptarget).dropYou(this);
}

ここのスクリプトが私を最も苦しめる問題のスクリプトです。
evalが返す値は、MCがドロップされた場所のインスタンス名というのはわかります(_droptargetを使っているから)。
ですが、次の
dropYou(this);
のthisの使われ方で、もう頭が錯乱してしまいました。
thisとは、オブジェクト参照のときだけに使うものであり、引数で使うものとは思っていなかったからです。
ここのthisがゴミ箱のMCのtheObjectに相当することはわかりますが、なぜ、thisとtheObjectは揃える必要がないのでしょう??

非常に支離滅裂で分かりにくいこと質問になってしまったかもしれませんが、引数の概念についてアドバイスを御願い致します。

投稿日時 - 2002-07-22 20:52:00

QNo.320010

すぐに回答ほしいです

質問者が選んだベストアンサー

こんにちは。回答が多少なりとも御役に立てるのも嬉しいですし、こうしてバイブルのことについてお話できるのもなかなか嬉しいです。
特にshevyさんはつくポイントがするどく、私がなにげに流してしまったところもしっかり見てらっしゃるので、たいへん勉強になります。(私もまだまだ勉強中の身ですので‥;)

さて
>それならば、最初からlevel0.marimoを
入れてコーディングしてしまえばいいのではないか?
と思いました。

この考え方は正しいです。マリモとゴミ箱しか存在しないこのサンプルにかぎっていえば、「this」で引数をわたす必要はないんですよね(もっとドラッグする対象の数が増えれば、thisの威力発揮!ですが)。
なのでshevyさんが手を入れたスクリプトも動く「はず」です。

on(release){
this.stopDrag();
eval(_droptarget).dropyou(level0.marimo); ←問題はココ。
}

trace(this)の結果は
_lecel0.marimo
でしたね。dropyou(level0.marimo)の引数のあたまに"_"が抜けてしまっているので、動かないんです。このシンタックスエラーをなおせば動きます。
バイブルの154Pにレベルの概念が出ているので、時間のあるときに読み合わせていただけると、いろいろわかるかと。loadMovieNum()とか使わないとあまり要らない概念ですけど(ふつうの場合は_level0 = _root)いつかはきっと役に立つ‥‥かも。
次ですが、

function dropYou(level0.marimo){ ...}(以下略)

これはエラーが出ますね。どうも「.」(ドット)が悪いようです。ドットが入っているものは引数にとれません(当然といえば当然ながら、知らなかった‥今回実験してはじめてわかりました)。それ以外にも「-」などの演算子がはいったもの、半角数字ではじまるものはエラーが出ます(変数やインスタンス名の「名付け」のルールと同じですね)。
で、スクリプトの方の話ですが、引数を固定にしたい場合はこういう書き方をする必要はないですよ。
このスクリプトを動くようにするには、以下のように書き換えます。

function dropYou(){
this.gotoAndStop("open");
_level0.marimo.dropped();
}

具体的には一行目のdropYou()の引数を空欄にします。このファンクションは引数を外から与えられる必要がないので、空欄(引数なし)でいいのです。
あと三行目の_level0.のあたまに「_」をつけて、これで動きます(もちろん_root.marimoでも動きます)。

さらに、ちょっとおまけですが、こういうふうにも動かせます。

namae = _root.marimo
function dropYou(){
this.gotoAndStop("open");
namae.dropped();
}

"_root.marimo"を"namae"という変数にして動かします。このnamae=_root.marimoのスクリプトを、たとえばフレームごとに変えておくと(たとえばフレーム3ではnamae=_root.usagi にしておくとか‥)同じファンクションでマリモが動いたりウサギ(を置いておけば)が動いたりしてくれますね。


以下は蛇足なのですが、フラッシュ5では「変数」には二種類あります。くわしくはバイブルの72Pから述べられていますが、「ローカル変数」と「グローバル変数」ですね。
で、最大の問題は「ローカル変数はそのファンクションの中のみ」で有効、「グローバル変数はそのMCの中のみ」で有効、ということです。つまりはどちらも「MCの外側に出ていけない」「MCの外側の変数を読むことができない」のです。(MXでは変数のスコープを指定できるので、可能らしい‥あんまりさわってないんですよねえ‥;)
で、「MCの外側と変数をやりとりする」方法がファンクションの引数です。これによって、自分の外側にある数値やインスタンス名を引数としてもらったり、自分の内側の変数を相手にあげたりすることができます。

どうも説明が冗長になってしまいましたが、ご参考になれば幸いです。
引数についてバイブル内でいちばんくわしいのは180Pあたりでしょうか。でも私、これでもわからず、はじめたばっかりのころ(実はこの春)プログラムにくわしい身内に「functionとかメソッドのうしろにくっついてる空のカッコ()っていったい何だ!?」とやむなく泣きついたことがあります。意味わからなくて。「オマケだよ」とか言われましたが。
あ、ラーニングアクションスクリプト、本屋で見ました。手ごわそうな本ですね。サンプルが実践的なので、興味があります。もうすこし安いといいのですが‥‥いやいや。いつか読んでみたいです。バイブルのみが頼りの身で、構造型だとスクリプト構成がどういうふうになるのかも興味があるので。

投稿日時 - 2002-07-24 12:13:33

お礼

hokuto_dsさん、有難う御座います!
お礼が遅れてしまいましたが、今日はかなりアクションスクリプトと格闘しっぱなしの一日でした。
そしてたった今、ほぼ今回の件の問題をクリアーした気分がしましたので、お礼を書けるに至りました。

それでは毎度のことながら、自己解釈論を書きます。
私が大きく勘違いというか、分かっていなかったのが、
functionで定義されるメソッドの引数と、そのfunctionで定義されたメソッドに送る際の引数の意味を混同していたからでした。

言わば、functionで定義されるメソッドにおいて表記される引数の値は、引数ボックスとでも言いましょうか、とにかく、ここにはどんな値でも入れることができるというわけです。その“どんな値”というのが、外部から、このfunctionで定義されたメソッドに送り込んでくる引数というわけですよね。

というわけで、送る側のメソッドは、具体的な値、式を書いてもそれが、functionで定義された引数ボックスに格納されるだけですから、例えば、
eval(_droptarget).dropyou(_root.marimo);
と書いても問題ないわけですよね。

ところが、
function dropYou(_level0.marimo){
this.gotoAndStop("open");
_level0.marimo.dropped();
}
というのは頂けないわけで、引数とは引数ボックス、要するに変数(みたいなもの?変数なのですかね・・)なので、変数やインスタンス名の名づけのルールに反するのでエラーになるというわけです。

さらに、
_level0.marimo.dropped();
と書いているので、既に_level0.marimoが具体的にそのオブジェクトの場所を指しているので、一行目に引数ボックスは必要なくなるので、
function dropyou(){
で構わなくなるというわけですね!
なにやら偉そうに書いてしまいましたが、
自分自身に教えるつもりで書いてみました。。。

また、
namae = _root.marimo
function dropYou(){
this.gotoAndStop("open");
namae.dropped();
}
というスクリプトでコーディングしてみました。
ちょっと自分で仕上げたスクリプトは、
間違っているような気もしていますが、
このnamaeに異なるパスを挿入するというアイデアは
理解できましたので、なんとか今後に活かせそうです。

>「MCの外側と変数をやりとりする」方法がファンクションの引数です。これによって、自分の外側にある数値やインスタンス名を引数としてもらったり、自分の内側の変数を相手にあげたりすることができます。

なるほど!!大納得です。function内の引数の意味を
理解した上で、hokutoさんが書いてくださった文章を読むと大納得しました。
function侮れず・・・!です。

今日は、本当にとことんスクリプトと向き合ってしまいました。でも楽しいですね。
お礼が送れてしまうことが非常に気掛かりだったのですが、なんとか理解してからお礼するのが礼儀だと思いましたので、お許しください。

本当に有難う御座いました。
また、近い日に、新たな質問をするかもしれませんが、
その際は、またご教授くださいますよう御願いします。

ラーニングなのですが、バイブルを理解しておられるhokutoさんなら、構造型とオブジェクト指向が混ざり合って、混乱するということはないと思いますよ。
私は、バイブルを一通り物にしてから、もう一度ラーニングを読み返してみようというように思っております。

投稿日時 - 2002-07-25 04:49:08

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

こんばんわ,RedCycloneです.
横槍かとは思いますが少し補足させて下さい.

関数定義の仕方はご存知の通り次のようになります.

function 関数名(引数1,引数2,・・・) { 文 }

関数定義で使用する引数ですが,扱いとしては”ローカル変数”ですね,自分の関数内でのみ有効です.ローカル変数ですから当然”変数”です.
従って,引数は”階層1.階層2.オブジェクト.変数”のような形を取りません.何故ならば,”階層1.階層2.オブジェクト1.変数”この変数はローカル変数ではないからです.

混乱してきたときは最初に戻って学習し直すと良いですね.

投稿日時 - 2002-07-24 20:26:56

お礼

回答有難う御座います。
なんとか、今回の質問のもやもやを昇華することができたと自負しております。

>ローカル変数ですから当然”変数”です.
従って,引数は”階層1.階層2.オブジェクト.変数”のような形を取りません.

変数名のルールに反するというわけですよね。
引数は、変数であり、もっと細かく言うと、ローカル変数である、と、これが分かっただけでもかなりの収穫です。

非常に参考になりました。
有難う御座いました!

投稿日時 - 2002-07-25 04:55:57

ANo.4

ちょっとこの前の回答の「蛇足」について蛇足の補足です;
今回問題になっているスクリプトと「変数」のスコープの話は関係ないです。ただファンクションの「引数」との関連で、うっかり書いただけでして。
要は、ファンクションの「引数」を使うと自分の外側にある変数をもらうことができて便利、とそういう蛇足です。

‥ほんとに蛇足だった(笑)。

投稿日時 - 2002-07-24 14:10:50

お礼

今なら、この蛇足の意味、分かりますよ!
嬉しいです。

>ファンクションの「引数」を使うと自分の外側にある変数をもらうことができて便利

これです、これです、私が言いたかったことは!
私流に言いますと、functionの引数ボックスには、外側にあるどんな変数でも格納できてしまうとでもいいましょうか。
うーん、素晴らしいです!

投稿日時 - 2002-07-25 04:52:00

ANo.2

こんにちは、shevyさん。
まず最初の問題ですが、

>theObjectという名のインスタンスが存在しないので???です。

これ、インスタンス名ではなくて「変数」みたいなものですよ。
ためしに「a」とかで考えてみると分かりやすい、かもしれません。
このスクリプトは「dropyouファンクションの定義」ですよね。「dropyou」がどんな引数をとってどんな動きをするかを決めているスクリプトです。
この function dropyou(theObject){...} は引数が theObject になってますが、これは「なんでもいい」んです。aでもbでもかわらないです(new とか false とか、スクリプトで使う「予約語」はだめですが)。要は、ファンクションというのは「外から呼ばれるもの」で、その時に「引数」も外から渡されるものです。渡された「引数」を、{...}に記述されたスクリプトの中で処理する時の「とりあえずの名前」が、引数です。この場合はそれが「theObject」だったと。

例でいってみましょう。都合上、このスクリプトが書かれたムービークリップの名前を「test」としておきます。
では、このファンクションを呼んでみます。フレームなりボタンなりに
_root.test.dropyou(3);
とか
_root.test.dropyou(suujidenakutemoii);
のように記述して、ファンクションを呼びますよね。この時、ファンクションの中では外から渡された「3」なり「suujidenakutemoii」なりを
function dropyou(theObject){.....} の「theObject」に代入して処理します。目には見えませんが、ここではいわば「theObject = 3」とか「theObject = suujidenakutemoii」 という代入式があるようなものです。

話を本文のスクリプトにもどします。
この「function dropyou(theObject)」はゴミ箱のMC中にありますが、ではこのファンクションを「呼ぶ」ほうを見てみましょう。
これはすでに言われたようにマリモのMC(MovieClip)内のボタンに書かれたスクリプト、
on(release){
this.stopDrag();
eval(_droptarget).dropyou(this);
}
からで、「dropyou(this);」というスクリプトでファンクションが呼ばれていますね。(evalについては理解されているようでよかった。私、最近御世話になってるんですがどうもこいつがいまひとつ使い切れない‥)
droptargetの引数、(this)。
これに「なに?」と思ってらっしゃるようですが、それを解決するいちばん早い方法は trace です。このスクリプトの最後に
trace(this);
って入れてみましょう。結果は
_level0.instance1
と出ます。(instance2かも‥置かれた順に名前がつくので)
この場合の_level0は「_root」と同じです。instance1は「インスタンスの名前」です。名前をつけてやらないとパレット上では「名前」のところが空白ですが、じつはシステムは勝手に名前を付けていて、置かれた順にinstance1 instance2 と連番でふっていってくれているのです。
ためしに、このインスタンスに marimo と名前を付けてみると、traceの結果は
_level0.marimo と出ます。
つまりこの「this」によって参照されるのは、このインスタンスの「絶対パス」なんですね。
dropYou(this);  という命令で、この「_level0.instance1」を引数として相手に渡しています。

では渡されたほう。(もうおわかりかもしれませんが)
function dropYou(theObject){
this.gotoAndStop("open");
theObject.dropped();
}
の (theObject)には、外から渡された「_level0.instance1」が入ります。
二行目はとばして、三行目にこれを代入すると
theObject.dropped();

_level0.instance1.dropped();
となります。
これを受けて_level0.instance1(マリモ)はfunction dropped(){..}を実行、と相成るのでした。ファンクションのキャッチボール。

n = 0 とかのnがsでもnatubateでもいいように、このtheObjectもなんでもいいです。ファンクションの中でそろってさえいれば、動くということです。

説明が長くてすみません。うまく説明できたかどうかたいへんあやしい。わかりにくかったら補足くださいね。
暑い上に(と、夏のせいにしてみる‥)、なぜか途中で一度説明が消えてしまい(夏のせい?)、ちょっと笑ってしまいました。
しかしthisをこういう形で引数にとるなんて、すっからかんに忘れていました。なんて便利!さすがバイブル、またしっかり読み直したいです。

投稿日時 - 2002-07-23 10:58:13

お礼

hokuto_dsさん、回答有難う御座います!!
いつもお世話になっております。
今回も私のために時間を割いていただき、本当に感謝しております。

theObjectとthisの意味が掴めました。なるほど、theObjectは変数みたいなものと解釈すれば、すっきり致しました。

そして、
trace(this);
なのですが、これまた目からウロコが落ちました。
traceは本当に便利ですね!
このtraceのおかげで、ひとまず、私は、
thisが、そのインスタンス自身への絶対パスを指すということがわかりました。


そして・・・、今回も自己解釈で以下のように発展させてみました。
hokuto_dsさんにお付き合いしていただきたく思いますので、御願い致します。


thisとtheObjectがそれぞれ共通して、
level0.marimo
(↑一応、MCにはmarimoというインスタンス名をつけたということで以下話をすすめます。)
を指しているということですから、
私は、それならば、最初からlevel0.marimoを
入れてコーディングしてしまえばいいのではないか?
と思いました。
以下のようにしてみたのです。

on(release){
this.stopDrag();
eval(_droptarget).dropyou(level0.marimo);
}

と、もう一つ、

function dropYou(level0.marimo){
this.gotoAndStop("open");
level0.marimo.dropped();
}

というようにしてみました。しかし、これだとゴミ箱のスクリプトがエラーになってしまいます。引数として、特定のインスタンスを揃えたのに、なぜいけないのでしょう?dropyouの引数にlevel0.marimoという指定そのものがスクリプトのルールを逸脱しているのでしょうか?
このようなことが起こるから、thisとtheObjectをわざわざ使わざるをえないのかなとも思うようになっております。
ちなみにlevel0.marimoの代わりに_root.marimoを入れて実験もしてみましたが、駄目でした。


再び長文の質問になってしまいましたが、つまりは、なぜleveo0.marimoという直接指定が駄目なのか、それだけのことですので、どうぞアドバイスを御願い致します。

それにしてもバイブルは読み応えがありますよね。
でも完璧に理解しながら進んでいこうとすると、本当によくこけてしまいます。とほほ・・・。

投稿日時 - 2002-07-23 21:47:53

ANo.1

こんばんわ RedCycloneです.
僕は標記書籍は読んだことがないのでアドバイスの立場でお答えします.
慣れないうちは多少混乱するかも知れませんが少しずつ確実にスキルアップして下さい.

>ここのthisがゴミ箱のMCのtheObjectに相当することはわかりますが
呼び出し側で dropYou(this) とすると,呼ばれる関数内で theObject = this となることは理解できるということですね.
thisというのは自分自身を表すキーワードで扱い方は他のMCと同様です.逆にthisというキーワードがなければ自分自身を表現できなくなってしまいますよね.

>なぜ、thisとtheObjectは揃える必要がないのでしょう??
thisとtheObjectはどちらもmovieClipですから”揃っています”.
呼ぶ側と呼ばれる側で引数の型が揃っていれば問題ありません.
(例えば dropYou(10) としたならば10は数値,theObjectはmomovieClipですから正常に動作しません.)

不明な点があればその旨補足下さい.

投稿日時 - 2002-07-23 01:13:47

お礼

RedCycloneさん、こんばんは。
回答ありがとうございます!!
お世話になっております。

thisの概念、理解できたと思っております。

>呼ぶ側と呼ばれる側で引数の型が揃っていれば問題ありません
なるほど!これにはすごく納得しました。
用は引数の型というわけですね。


もうしばらくですが、hokuto_dsさんに本書の細かい点について聞いておりますので、回答を締め切ることが出来ませんことを御了承ください。

本当に有難う御座いました!

投稿日時 - 2002-07-23 21:53:24

あなたにオススメの質問