はじめに
はじめてのQiita投稿です。お手柔らかに……。
※編集・コメントありがとうございます。即適応させていただきました。
(作者: twitter @merusaia)
RPGツクールMVというツールは、エディタで出来ることもさることながら、
javascriptを使うことで、ツクール至上最も拡張性の高いものに仕上がっていると思います。
他のプログラミング言語を使ってゲームを作っていた人も、
「これはスクリプトを触れば色々出来るんじゃない?」と
ワクワク期待を膨らませられます(筆者はC#から移行してます)。
概要
ですが、CやJava方面から見ると、javascriptの各種判定式は、かなり特殊です。
他の言語と一緒に考えてたら、痛い目みます。。
詳しくは、それぞれのキーワードをぐぐってみてください。罠にハマります。
そこで、なるべくjavascriptの罠にはまらないように、
事前にツクールMVのエディタで、値や各種挙動をチェックできる
スクリプトを作りました。
使い方
ツクールMVのエディタ「スクリプト」で、以下の10行を貼り付けてください。
そして、【好きな初期値】に変数値を入れて、
右クリックメニューで「テスト」してください。
変数「_a」の判定式が、それぞれどんな反応が返ってくるか、事前にわかります。
まだ必要な判定がアレば、お気軽にご指摘・判定式の追加をお願いします。。
var _a = 【好きな初期値】; // ここの「a = 」の後に【好きな初期値】を入れてね。
alert(
"「var _a = 【好きな初期値】」の時の判定式だよ。"+"\n_aの値: "+_a
+"\n_a==0: " + (_a==0));
alert(
"_a instanceof Number: " + (_a instanceof Number) +" // 「0 instanceof Number」はfalseだから、気をつけてね。new Number(0)はtrue。\n_a instanceof String: " + (_a instanceof String) + " //「”あ” instanceof String」はfalseだから、気をつけてね。「new String(”あ”)」はtrue。"
+"\n_a instanceof Object: " + (_a instanceof Object) +"\n_a instanceof Boolean: " + (_a instanceof Boolean)
+"\n_a==undefined: " + (_a==undefined) +"\n_a==null: " + (_a==null) + "\n_a===undefined: " + (_a===undefined) +"\n_a===null: " + (_a===null)
+"\n_a===NaN: " + (_a===NaN) +"\nNumber.isNaN(_a): " + Number.isNaN(_a) + "\nNumber.isFinate(_a): " + (Number.isFinite(_a)) + "\n_a === Infinity: " + (_a === Infinity) + "\n_a === -Infinity: " + (_a === -Infinity)
+"\nparseInt(_a): " + parseInt(_a) +"\n_a || 0: " + (_a || 0) );
番外編:よく忘れる判定式の挙動 (他にもたくさんあるわな)
以下、自分用のメモの貼り付けで恐縮ですが、こんなのがあります。
エディタのコモンイベントなどに一括管理して、よく見返しております…。。
罠だらけだ…><。
◆注釈:判定演算子、isNaN、Number.isNaN、「a || 0」などについてについて。
◆注釈:NaN === NaN は falseです。。。仕様おかしい。。
: :NaN > 0 はfalseです。
: :NaN < 0 はfalseです。
: :NaN != null はtrueです。
: :NaNの判定には、Number.isNaN(a)を使います。isNaN(a)と書いちゃダメです。信頼性に欠けます。
◆スクリプト:if(NaN < 0){
: : alert("数えられない数は0より小さいよ。ここは永久に実行されないから注意してね。");
: :}else{
: : alert("数えられない数は0より小さく…ないよ。知らないけど。");
: :}
◆スクリプト:if(NaN > 0){
: : alert("数えられない数は0より大きいよ。ここは永久に実行されないから注意してね。");
: :}else{
: : alert("数えられない数は0より大きく…ないよ。知らないけど。");
: :}
◆スクリプト:if(NaN != 0){
: : alert("数えられない数NaNは0じゃないよ。だから比較すらできないから、>や<は全部falseだよ。");
: :}
◆スクリプト:if(NaN != null){
: : alert("数えられない数NaNはnullでもundefinedでもないよ。だからNumber.isNaN()でちゃんと比較しないといけないよ。");
: :}
◆スクリプト:if(isNaN('a')){
: : alert("isNaN('a')は、falseだよ。"
: :+"だって、数値"+Number(isNaN('a'))+"に変換できちゃうもんね~。や~いや~い、ひっかかった~(絶望)");
: :}
◆スクリプト:if(Number.isNaN('a')){
: : alert("ここは実行されないよ。");
: :}else{
: : alert("Number.isNaN('a')もfalseだよ。\n"
: :+"文字列が入っている可能性があるときは、NaNか調べるときは、Number.isNaN(a)を使おうね。");
: :}
◆スクリプト:var _num1 = NaN;
: :_num1 -= 50;
: :if(Number.isNaN(_num1)){
: : alert("NaNなものに、何を演算しても、NaNのままだよ");
: :}
◆注釈:■NaNの仕様がいろいろとよくわからない剣でぶっ刺されるについて
◆注釈:ここ、気をつけて。もはやわけわかめだよ‥。
◆スクリプト:alert(isFinite(NaN)); // falseです。NaNは数えられない数、比較すらできないんですから、当然ですよね。
◆スクリプト:alert(Number.isFinite(NaN)); // falseです。NaNは数えられない数、比較すらできないんですから、当然ですよね。
◆スクリプト:alert(isFinite(Infinity)); // falseです。無限は数えられない? ・・え? そうです・・かね。
◆スクリプト:alert(Number.isFinite(Infinity)); // falseです。無限は数えられない。そうなんですね。
◆スクリプト:alert(Number.isFinite(undefined)); // falseです。そうですよね。
◆スクリプト:alert(isFinite(undefined)); // falseです。そうですよね。
◆スクリプト:alert(isFinite(null)); // trueです。。なぜに。。。
◆スクリプト:alert(Number.isFinite(null)); // falseです。そうですよね。
◆スクリプト:alert(isFinite("12")); // trueです。文字列のままでも、数えられるんだな、これが。
◆スクリプト:alert(Number.isFinite("12")); // falseです。Number.は、そういう卑劣なことは許しません。
◆注釈:ここ、気をつけて。もはやわけわかめだよ‥。
◆スクリプト:NaN === NaN // falseを返す!!!
: :function isReallyNaN(x) {
: : return x !== x; // xがNaNであればtrue, それ以外ではfalse
: :}
◆スクリプト:// 標準で用意されているisNaNにNaNを渡すと確かにtrueが返ります。
: :// ただ、暗黙の型変換によって引数を数値へと変換してしまう為、NaN自身でなくても、NaNへと変換される類のものに対してもtrueを返してしまいます。
: :// isNaNはNaNであるかの判定ではなく、引数が数値へ変換可能かどうかの判定に使われるみたいです。
: :isNaN(NaN); // true
: :isNaN("foo"); // true
: :isNaN(undefined); // true
: :isNaN({}); // true
: :isNaN({ valueOf: "foo" }); // true
: :// 新しく作られたNumber.isNaNは、 x != x と同値です。
: :Number.isNaN(NaN); // true
: :Number.isNaN('NaN'); // false
: :alert(Number.isNaN(Infinity)); // false
◆注釈:javascriptでは、Boolean(a)は、
: :aが値が省略された場合や、値が 0, -0, null, false, NaN, undefined
: :あるいは空文字列 ("") であった場合、false の初期値を持ちます。
: :それ以外のあらゆる値は、"false" という文字列も含めて、trueです。
◆スクリプト:alert(Boolean(NaN)); // false
◆スクリプト:alert(Boolean(false)); // false
◆スクリプト:alert(Boolean("false")); // true
◆スクリプト:alert(Boolean(Infinity)); // true
◆注釈:ここ、気をつけて。if(a)は、aがnull, undefinedの時だけじゃなく、0, ""、NaNの時もfalse だよ。
◆スクリプト:var a = '';
: :alert(!!a); // if(a)がtrueかを返す。if('')はfalse。
: :a = "";
: :alert(!!a); // if(a)がtrueかを返す。if("")はfalse。
: :a = 0;
: :alert(!!a); // if(0)はfalse。
: :a = "0";
: :alert(!!a); // if("0")はtrue。
: :a = " ";
: :alert(!!a); // if(" ")はtrue。
◆注釈:「a || 0」という記述はよく見るけど、0、""、NaNの時も0になるよ。特に""が注意!
◆スクリプト:var a = Infinity;
: :alert(!!a); // if(Infinity)はtrue。
: :var a = NaN;
: :alert(!!a); // if(NaN)はfalse。…ええ~~~!????。
: :
: :// なるほど。だから以下は、NaNでも0になるのか。
: :var a = a || 0;
: :// 上の1行は、下の3行と同じ意味、ですよね。
: :if(!a){
: : a = 0;
: :}
皆さまもお気をつけて……。