広告

posted by fanblog
「ここにブログの名前を入れます」は更新を終了しました。記事はすべて新ブログ「Big Bang」に移転済みです。記事のタイトルをクリックすると新ブログの該当記事に移動します。そちらでお楽しみください。

ソースのバグの作り方 -if文のカッコ-

先日の記事「最新記事だけ日付を消す新スクリプト -お知らせ枠の設置-」のソースを実際にマスクドライダー17号さんが設置したところ、次の事情でうまくいきませんでした。(記事のソースは、うまくいくように修正済みです)

最初のソースコードは、次のものでした。

<script type="text/javascript">date=document.querySelector('div.entryDate');if(date){date.style.display='none';}</script>

このコードは、間違っていません。
実際に、マスクドライダー17号さんのブログのソースをメモ帳にコピペして、上の通り作業してブラウザで開くと、ちゃんと消えたのに、本当のブログにアップロードすると、消えませんでした。

なぜかというと、{} の2つのカッコが、おかしな形で変換されていたのです。

ファンブログのエディタを通すと、時々なぜかわからない形でソースコードが変わってしまうことがあります。それで、ソースを書き換えて対処しました。

変更点は、次の通りです。(記事のソースは変更済みです)

{} を削除する。
おかしく変換されてしまう2つの文字を削除することで、おかしな部分がなくなったので、正しく動きました。

なぜ、{} を削除できたのか?

逆に言うと、{} は不要なものだったのか?という疑問があるかもしれません。この場合は、なくてもいいものでした。だから、消すだけで対処できました。これは次の条件にあっていたためです。つまり幸運だったのです。

if文の次の処理は条件にあえば実行される。実行する処理が複数ある時はその部分を、{ と } で囲む。

JavaScriptに限らず、C系統のif文の書き方は次の構文です。

if(条件){ 実行内容 }

今回の場合は、if(date){date.style.display='none';} が、その部分です。

これは、if('object'==typeof date){date.style.display='none';} と書きかえても同じです。

この文を日本語に直すと、dateがオブジェクトなら、dateのスタイルシートdisplayをnoneにしなさいとなります。

これは実行内容がひとつです。「dateのスタイルシートdisplayをnoneにしなさい」のひとつだけを実行するので、カッコがなくても正しく動きます。しかし、もし実行内容が複数だと意図どおりには動きません。

たとえば、「dateがオブジェクトなら、dateのスタイルシートdisplayをblockに、色を赤にしなさい」という内容であったらどうでしょう。ソースコードはこうなります。

if(date){
	date.style.display='block';
	date.style.color='#ff0000';
}

改行と行のはじめの空白(インデント)は見やすくするためにつけていますが、コンピュータの内部処理では無視されます。if(date){date.style.display='block';date.style.color='#ff0000';}と書いたのと同じようにコンピュータは処理するのですが、人間が見やすくするためにつけています。

JavaScriptでは、{から}までのブロックは、ひとつの命令として扱います。

これで、dateがオブジェクトなら、{から}までのブロックを実行しなさいとなります。ブロックの内容は「displayをblockに」と「色を赤に」の2つです。

ここでカッコをとってみます。

if(date)
	date.style.display='block';
	date.style.color='#ff0000';

これはどのように扱われるか?次のようになります。

処理1. dateがオブジェクトなら、dateのスタイルシートdisplayをblockにしなさい。
処理2. dateのスタイルシートのcolor(色)を#ff0000(赤)にしなさい。

処理1はdateがオブジェクトならという条件判断をされますが、条件判断はひとつ目の処理で終了します。よって、処理2はdateがオブジェクトであろうとなかろうと実行します。

この例だとdateというオブジェクトがあれば、結果は同じです。カッコがあってもなくても、「dateがオブジェクトであった場合」の結果は、「スタイルシートのdisplayをblock」にして「スタイルシートのcolorを#ff0000」にします。

dateがオブジェクトである限り、カッコがあってもなくても、思ったとおりの結果になるのです。だから例えば、この命令をマスクドライダー17号さんのブログに適用すれば正しく、意図どおりに動きます。なぜなら、マスクドライダー17号さんのブログでは日付が消えているのだから、dateオブジェクトがあるのです。

しかし、dateがオブジェクトでなかったら、どうなるでしょう?適用されるはずのdate.style.colorが存在しないかもしれません。その場合はエラーになります。だから他の人のブログで使えばエラーが出るかもしれません。

つまり、これはカッコがないことによって気がつかないバグになっています。

カッコのあるなしで、意図とは違う結果を生み出すことがあります。バグというのはそうやって生み出されるのです。

新ブログ「Big Bang」で続きを読む