2010-11-30 8 views
8

で安全にStringに何かを変換するには? test.toString()を呼び出さずに、typeof x == "string"のチェックを使わずにチェックをします。非文字列を許可したいからです。どのようにJavaScriptの

注:これは、コンテンツページのjsスコープのオブジェクトを扱うFF拡張機能です。

+2

あなたは 'のtoString()'を呼び出すことなく、返すために何を期待していますか? – casablanca

+1

さて、JSONシリアライザは常にあります。 – cdhowie

+1

サンプル構文を修正しました。 –

答えて

5

JavaScriptがどのオブジェクトはあなたが説明した方法で「悪コード」に対して脆弱であることを意味、Object.prototype自体を含め、あなたのスクリプトにアクセス可能である任意のオブジェクトほとんどのプロパティを変更することができます。

悲しいこと
function safeToString(x) { 
    switch (typeof x) { 
    case 'object': 
     return 'object'; 
    case 'function': 
     return 'function'; 
    default: 
     return x + ''; 
    } 
} 
+0

[Lodash array](https://lodash.com/)のようなものを使用して、もっと細かくする必要がある(例: '[1,2,3]'から '' 1,2,3''CSVに変換したい) docs/4.17.4#isArray)/ [オブジェクト検出](https://lodash.com/docs/4.17.4#isObject)をオブジェクトのケースに入れることができます: 'return _.isArray(x)&&!_。いくつか(x、_.isObject)? _.toString(x): 'object'; ' – jmmygoggle

5

あなたの(toString: function(){alert("evil code"); return "test";})はここでも解析されません。構文エラーが発生します。 ()の代わりに{}を使用したかったと思います。

""+test; 
""+2; // "2" 
""+4.5 // "4.5" 
""+[1, 2, 3] // "1,2,3" 
""+{} // '[object Object]' 

しかし、ここでは、安全にオブジェクトを変換する本当の方法はありません。

は、通常は キャストを実行するために、空の文字列とプラス演算子を使用することができます。

あなたはそれが'[object Object]'を返す通常のtoString方法にフォールバックしますその後、オーバーライドされたメソッドを取り除くためにdelete test.toStringを使用することができます。 test.toString.toString()toStringメソッド自体を文字列に変換することもできます。

"function() { alert("evil code"); return "test"; }" 

それはあなたが正確にここで何をしたいかはあなた次第です。

+1

これは暗黙のうちに "悪" toStringを呼び出します。 –

+0

@Matthew実際にはここ5:30です。彼のサンプルコードも壊れていて、更新する予定です。 –

+0

答えを更新してください。 –

4

1つのオプションは次のとおりです。

Object.prototype.toString.call(test) 

これが与える:テストの場合

"[object Object]" 

を。基本的には、型情報を提供するだけです。しかし、正確なシナリオがここにあるのだろうか。邪悪なオブジェクトはどのようにページに読み込まれますか?彼らがページ上で任意のコードを実行できる場合は、基本的に運が悪いです。とりわけ、Object.prototype.toStringを再定義することが可能です。

+1

'Object.prototype.toString'をオーバーライドすることが可能であるため、これでも絶対確実ではありません。 – casablanca

+0

@casa、true。これは実際には、自己完結型のオブジェクトをページに渡すだけであれば役立ちます。グローバルのプロパティを変更できる場合、すべてのベットはオフです。 –

+0

ここにキャッチがあり、邪悪なコードは私のコードとは異なる範囲で作成されています。これは、コンテンツページのスコープを扱うFFのextです。したがって、そのスコープから来るオブジェクトは異なるObject.prototypeを持つ必要があります。したがって、 'Object.prototype.toString'を使用することは安全です。 – erikvold

1

、@Matthew Flaschenの(現在受け入れられている)の答え:「悪のコードは、」実行されないことを保証する唯一の方法は、このような何かを行うことですので

のみプリミティブは、安全であることが保証されています(私はとして、なぜ見当がつかない

console.log("" + Symbol("foo")); 
// results in an exception: 
// `Uncaught TypeError: Cannot convert a Symbol value to a string` 
// (at least in Chrome as of this writing). 

https://jsfiddle.net/L8adq9y4/

:ES6/ES2015からSymbolクラスでは動作しません。は完璧なtoString()方法:)

console.log(Symbol("foo").toString()); 

https://jsfiddle.net/v1rqfhru/

を持っている解決策は、しかしあります:String()機能がStringに(少なくとも私が試したもののうちの)任意の値に変換することができるようです。だから

console.log(String("A String")); 
console.log(String(undefined)); 
console.log(String(null)); 
console.log(String({value: "An arbitrary object"})); 
console.log(String({toString: function(){return "An object with a toString() method";}})); 
console.log(String(function(){return "An arbitrary function"})); 

https://jsfiddle.net/6uc83tsc/

String()にあなたが好きなものを渡し、あなたはかなり良い結果を得るでしょう:それも、それが存在する場合はtoString()を呼び出します。

+0

"好きなものを 'String()'に渡すと、かなり良い結果が得られます。まあまあ。 'String([Symbol( 'AAAA')])'は "Uncaught TypeError:シンボル値を文字列に変換できません"を返します。 –

0

lodash toStringメソッドを使用できます。

_.toString(null); 
// => '' 

_.toString(-0); 
// => '-0' 

_.toString([1, 2, 3]); 
// => '1,2,3' 

Link to documentation