2007年11月27日 02:00 [Edit]

javascript - Object.toSource() for non-FireFox!

404 Blog Not Found:javascript - お伺い - Object.prototype.clone()」でJKL.dumperを使ってみて、FirefoxのObject.toString()の挙動との不一致が気になったので、FireFoxでなくても使えるObject.toString()を作ってみました。

自分で言うのもなんですが、これは禿しく使えます。


とりあえず、SafariとOperaで動くところまで確認してあります。[追記:IE6 (Via CrossOver Mac 体験版)でも動きました! Mac IE 5だとさすがにNG]、FireFoxのようにすでにObject.toString()を内蔵しているものでは何もしません。

ソース
(function(){
    /* atomic objects */
    if (!Boolean.prototype.toSource)  Boolean.prototype.toSource = function(){
        return this.toString();
    };
    if (!Number.prototype.toSource)    Number.prototype.toSource = function(){
        return this.toString();
    };
    if (!String.prototype.toSource)    String.prototype.toSource = function(){
        return '\"' + this.toString().replace(/[\\\"\']/g, function(m0){
            return '\\' + m0;
        }) + '\"';
    };
    if (!Date.prototype.toSource)        Date.prototype.toSource = function(){
        return '(new Date(' + this.valueOf() + '))';
    };
    if (!RegExp.prototype.toSource)    RegExp.prototype.toSource = function(){
        return this.toString();
    };
    /* and built-ins */
    if (!Function.prototype.toSource) Function.prototype.toSource = function(){
        return this.toString();
    }
    if (!Array.prototype.toSource)       Array.prototype.toSource = function(){
        var src = [];
        for (var i = 0, l = this.length; i < l; i++){
            src[i] = this[i].toSource();
        }
        return '[' + src.toString() + ']';
    };
    if (! Object.prototype.toSource)    Object.prototype.toSource = function(){
        var src = []; // a-ha!
        for (var p in this){
            if (!this.hasOwnProperty(p)) continue;
            src[src.length] = 
                p.toSource() + ':' 
                + (this[p]               ? this[p].toSource() :
                   this[p] === undefined ? 'undefined' : 'null');
        }
        // parens needed to make eval() happy
        return '({' + src.toString() + '})';
    };
})();
サンプル
Source:
stdout:
stderr:

これを作った過程で、先ほどのObject.clone()Object.hasOwnProperty()を使えばうまく行くことに気がつきました。後ほど訂正予定。

Enjoy!

Dan the JavaScripter


この記事へのトラックバックURL

この記事へのトラックバック
うーん、それもそうなんだけど.... 最速インターフェース研究会 :: JavaScriptにおけるdeep cloneまず、Object.prototypeにメソッドを生やしてしまうとfor inでキーを列挙するときにいちいちhasOwnPropertyを使わないといけなくなるので普通は使いません。 で、JSONにする....
javascript - uneval() for the rest of us!【404 Blog Not Found】at 2007年11月27日 19:12
■Firefoxに危険度「高」の脆弱性、最新版にアップデートを(Yahoo Newsより)http://headlines.yahoo.co.jp/hl?a=20071127-00000035-zdn_ep-sci 仏セキュリティ機関FrSIRTは11月26日、Mozilla Foundationの「Firefox」ブラウザおよび「Seamonkey」スイートで3件の脆弱性が発...
Firefoxに危険度「高」の脆弱性【ただいまのニュース速報】at 2007年11月27日 17:20
この記事へのコメント
数値の0, 空文字''などはfalsyなので、Object.prototype.toSource()で、たとえば0はnullになってしまいます。

IE8で、下のようになることを確認しました。

var o = {a:0,b:""};
var s = o.toSource();
p(s); // --> ({"a":null,"b":null})

まずundefined, nullかどうかを明示的に判定すべきでしょうか?
Posted by haluka at 2010年12月17日 23:45
ソースの中は当然そのままで合っています。が……

"JKL.dumperを使ってみて、FirefoxのObject.toString()の挙動との不一致が気になったので、FireFoxでなくても使えるObject.toString()を作ってみました。" =~ s/Object.toString()/Object.toSource()/g

"FireFoxのようにすでにObject.toString()を内蔵しているものでは何もしません。" =~ s/Object.toString()/Object.toSource()/

ではないかと。
Posted by Yuichirou at 2007年11月27日 16:24
Yuichirouさん、
いいえ、ソース中のtoString()はわざとです。
Dan the Man Who Knows What He Means
Posted by at 2007年11月27日 11:32
s/Object.toString()/Object.toSource()/g

かなりFatalなtypo。意味を誤解しかけた。
Posted by Yuichirou at 2007年11月27日 09:36