JavaScript で文字列や日時フォーマットを自前でやる
思うところがあったのでやった。基礎練習とか素振りみたいなものです。
JavaScript の標準の文字列出力はあまりに貧弱すぎるからそこらへんなんとかなんないかやってみた。ライブラリを使うなら日時フォーマットについては Underscoe.String.js とかあるし、日時は Moment.js あたりがいいらしい。
Underscore.string
Moment.js | Parse, validate, manipulate, and display dates in javascript.
文字列の format
すごく単純な例
JavaScript テクニックバイブルにあったのを参考にした。
JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技
- 作者: JSサポーターズ
- 出版社/メーカー: 技術評論社
- 発売日: 2012/08/31
- メディア: 単行本(ソフトカバー)
- 購入: 38人 クリック: 1,794回
- この商品を含むブログ (11件) を見る
function pf() { var tmp = arguments[0]; for (var i=1; i < arguments.length; i++) { tmp = tmp.replace(/%s/, arguments[i]); } return tmp; } pf("This %s is %s", "name", "ore") // This name is ore
やってることは可変長引数をとってやって %s と決め打ちしたところを全部置換してるだけ。arguments[0] で元の文字列を受け取って for ループで i=1 以降を使うことで対応する。というやりかた。
もうちょっと拡張する - 自作
Python の "string".format(arg) をやってみた。で、似たようなことをやってるような人はそれなりにいたので結局だいぶ参考にしてしまったけど、まずは頭から消してどうにか自前でやってみた。あんまり String とかグローバルなところは拡張したくなかったけど、まあ、習作。
/** * String.prototype.format * @param String.prototype.arg */ String.prototype.format = function (arg) { // this = String var tmp = this; // Object if (typeof arg === "object"){ for (var elem in arg){ tmp = tmp.replace("{" + elem + "}", arg[elem]); } // String } else { for (var i=0; i < arguments.length; i++) { tmp = tmp.replace("{" + i + "}", arguments[i]); } } return tmp; }; // オブジェクトで渡す "abc {hoge} {moge}".format({hoge: "text1", moge: "text2"})) // abc text1 text2 // 文字列を複数いれる "abc {0} {1}".format("text1", "text2"); // abc text1 text2
これもわりと泥臭くて、結局文字列を愚直に組み立てて replace で置換してる。
もうちょっと拡張する - 参考資料
JavaScript で文字列フォーマットを実装してみた(sprintf もどき) | TM Life のままだけど、変数名はちょっとかえた
/** * String.prototype.format2 * @param String.prototype.format2arg */ String.prototype.format2 = function (arg) { // init var func = null; // Object if (typeof arg === "object"){ func = function (regexp, key) {return arg[key]; }; } // String else{ // 一度格納しないと末尾しか拾わない var args = arguments; func = function (regexp, key) {return args[key]; }; } // this = String // replace の第2引数は関数でもよい! // そのとき return された文字列をつかう // g で繰り返しているから key が増えていく return this.replace(/\{(\w+)\}/g, func); };
あたまいいなー。なにを知らなかったかというと、 string.repace の第2引数で関数がとれるということ。マッチした第一引数が regexp としてはいってきて、それを args[key] で置き換えてやる。ということをしている。
簡易日時フォーマット
けっこう泥臭いものをつくった。そのかわり、上で自作した string.format 関数をつかった
/** * strftime * @param d */ function strftime(d) { var date_format = "{0}年{1}月{2}日:{3}時{4}分{5}秒".format( d.getFullYear(), d.getMonth() < 10 ? "0" + d.getMonth() : d.getMonth(), d.getDate() < 10 ? "0" + d.getDate() : d.getDate(), d.getHours() < 10 ? "0" + d.getHours() : d.getHours(), d.getMinutes() < 10 ? "0" + d.getMinutes() : d.getMinutes(), d.getSeconds() < 10 ? "0" + d.getSeconds() : d.getSeconds() ); return date_format; } // strftime(new Date())) // "2012年01月02日:03時04分05秒"
いいかんじです
まあ
素振りです。JS の標準機能が貧弱すぎるなら、自分で武器を作れるようにならなくてはいけない。