rcmdnk's blog

入門者のJavaScript (ブルーバックス)

ちょっとサイトで上手く表示されない所があって 問題は埋め込んでたJavaScriptでデフォルト引数を使ってた せいだった件。

JavaScript関数で引数で=を使ってのデフォルト引数

Octopress(Jekyll)の設定変数をJavaScriptから使うjekyll_varという値を作ってこれに

1
2
3
4
5
jekyll_var = function(i,j=null){
  if(j!="page" && i in jekyll_var.site)return jekyll_var.site[i];
  else if(j!="site" && i in jekyll_var.page)return jekyll_var.page[i];
  else return null;
};

と言った形の関数を当ててました。

第一引数で与えた名前の値を探す関数で、 第二引数は与えなければsitepageの中値を順に探して、 pageとかを指定するとその中だけを探す様にした関数です。

取り敢えずFirefoxを普段使ってるのでそこでは動いて 良かったな、とおいておいたんですが、ちょっとGoogle Chromeで見てみたら JavaScriptが動いてないような状態になってました。

さらにSafariでもダメ。

Chromeで要素の検証(Inspect Element)を開いてコンソールを見てみると

Uncaught SyntaxError: Unexpected token = 

というエラーが上の関数を定義する所で出ていました。

Firefoxで見る限りはエラーが出てません。

で、ちょっと探してみると、この様なデフォルト引数は 現状Firefoxでのみ扱える仕様になっているようです。

Default parameters - JavaScript MDN

Firefoxでは随分前から(15.0なので2012年)使える様になってますが、 他ではまだ未定な感じ。

ということで、上の関数はFirefox以外ではエラーになりますなんてこった。

Firefoxはこいうのが結構あって先進的で便利なんですが、 チェック用に使うには危険。。。

Google ChromeではまだJavaScriptでstr.startsWith()が使えない

これも同じ様な失敗の話。

他のブラウザでも使えるデフォルト引数

関数の引数部分にデフォルト値は書けませんが、 JavaScriptでは引数がいくつかあっても 関数を呼ぶ時に引数の数が足りなくてもエラーは出ません。

この場合、足りない部分にはundefinedが入ります。

なので

1
2
3
4
5
6
jekyll_var = function(i,j){
  var j = (j !== undefined) ? j : null;
  if(j!="page" && i in jekyll_var.site)return jekyll_var.site[i];
  else if(j!="site" && i in jekyll_var.page)return jekyll_var.page[i];
  else return null;
};

こんな感じの事をしておけば上で書いたj=nullの物と同じ動作になります。

!=ではなくて厳密な!==を使うのは jnullを渡した場合とundefinedな場合で区別するため 1

ただ、上の場合は余り意味ありませんが。

また、以前まではこのundefinedの値が上書きされる可能性がありました。 なので上書きされると全て狂う、と言う危険性があったため、 undefinedそのものを使う代わりに

1
if(typeof(hoge) != "undefined")...

みたいにタイプを見て判断する事が常識だった様です。

ただ、現在はundefinedの上書きは禁止されてるので j !== undefinedで十分です。

この仕様は ECMAScriptというJavaScript等の標準を定めた物で決まっていて、 undefinedに関しては2009年に公開されたECMAScript 5から そのような仕様になっている様です 2

ちなみに上のFirefoxでしか出来ないデフォルト引数の書き方は ECMAScript 6の仕様に入る予定らしく、 将来的にはどこでも使えるようになるものだと思います。

Firefoxでは他にも色々と ECMAScript 6の仕様を既に取り入れています。

Mozilla における ECMAScript 6 のサポート - JavaScript MDN: https://developer.mozilla.org/ja/docs/Web/JavaScript/ECMAScript_6_support_in_Mozilla

逆に言うとここに載ってる仕様はまだ他のブラウザでは使えない可能性が大きいので 気をつけないといけません。

まとめ

上ではundefinedと比べたりするのを書きましたが、 上の関数ではそこまでする必要もないので単に j=nulljとデフォルト値を消すだけにしました。 これで上手く動くようになりました。

ということでjekyll_varを入れたのが2月位なので それから数ヶ月間ChromeとかではJavaScriptが効かない状態だったみたいですね。。。

まあ聞かなくてもただページを読むだけならそれ程困るものでもないので そもそも正常を知らないと分からないしそういうものだと思われてた感。 (自分自身はFirefoxをよく使いますが、このブログを見に来る人は ChromeのがFirefoxの倍くらい居て、実はSafariのがFirefoxよりちょっと 多かったりもするのですが。)

まあいずれにしろこれで治ったと思うので、 例えば各ページに付いてる ソーシャルボタン にちゃんと数字が表示されてるとか、 Monthly Archives の去年以前の物が畳み込まれてるだとか、 Indexページで各ポストの表示の全体がリンクになってる とか、 サイドバーのランダムリスト がきちんとシャッフルできたり働いてるとか 確認出来るかと。

何かおかしかったらコメントでもTwitterでもなんでも教えてくれるとうれしいな、と。

後、これのせいで ブログがコピーされた事をGoogleアナリティクスでイベントトラッキングする とか Mandrillを使ってJavaScriptだけでメールを送る とかが上手く行ってない部分があったかも。

確かに2月にいきなりコピーの数が大きく減る事があって PVは変わらないのになんでかな?と思う事はあったのですが 多分これのせい。 これらの中ではjekyll_varの値を使ってたりするので 動いて無かったんだと思います。 (これでまたいきなり増えたら。)

一方でAnalyticsのビュー数はそんなに大きく変わってないので大丈夫だったのかな?とも。 ちゃんと調べればどこからどこまで動いてたのかわかると思いますが、 取り敢えず動く様になったからいいかな。

今度からは特にJavaScriptいじった際にはちゃんとChromeとかでも確認しないと。。。

Sponsored Links
Sponsored Links

« Androidスマホで着信拒否する Facebookのカウント取得を改善 »

}