2017-12-12 15 views
1

は、次のクラス宣言を考えてみましょう:私たちはここに見ることができるようtest1の文字列化バージョンを評価Function.prototype.toString()は、有効なJSを返すとは限りません。どうして?

class A {} 
A.prototype.test1 = function test1() { console.log("test1") } 

は、有効なJSを生成します。

const a = new A 
eval(`(${a.test1})`)() // outputs "test1" 

しかし、我々は根本的に異なるで私たちのクラスを構築するが、場合同等の方法:

class B { 
    test2() { console.log("test2") } 
} 

test2 FAIの文字列化バージョンの評価LS:

const b = new B 
eval(`(${b.test2})`)() // SyntaxError: Unexpected token { 

(それはクラス宣言に埋め込まれたときを除いて有効なJSされていないtest2() { console.log("test2") }に文字列化された)

私はたとえば"".indexOf.toString()ため、評価可能でないという文字列化されたネイティブ関数を理解することができますが含まれる文字列を返します。 [native code]と私はそれを受け入れる。

しかし、Function.prototype.toString()がユーザ定義関数(つまり、ソースコードが利用可能な関数)で呼び出されると、有効で評価可能なJSが生成されることを保証する方法はありませんか?

+0

"*クラス宣言に埋め込まれている場合を除いて*" - はい、そうです。 – Bergi

答えて

3

しかし、ユーザー定義関数で呼び出さFunction.prototype.toString()(つまり、ソースコードが入手可能であるからである機能)の有効な、評価可能なJSを生成することを保証する方法はありませんでしょうか?

いいえ。機能の種類によって異なります。 The specification requires the following

toString表現要件:

  • 文字列表現がFunctionDeclarationのFunctionExpressionの構文を持っている必要があり、GeneratorDeclarationGeneratorExpressionAsyncFunctionDeclarationAsyncFunctionExpressionClassDeclarationClassExpressionArrowFunctionAsyncArrowFunction、またはオブジェクトの実際の特性に応じMethodDefinition
  • 表現文字列内の空白、行終端文字、およびセミコロンの使用と配置は実装依存です。
  • オブジェクトはECMAScriptのコードを使用して定義され、返される文字列表現がMethodDefinition又はGeneratorMethodの形ではない、その後表現はその語彙文脈でevalを使用して、文字列が評価される場合、そのようなものでなければならない場合元のオブジェクトを作成するために使用された語彙コンテキストと同等ですが、新しい機能的に同等のオブジェクトになります。その場合、返されたソースコードは、たとえこれらの「余分な」名前が元々スコープ内にあったとしても、元の関数のソースコードによって自由に言及されていない変数を自由に記述してはなりません。
  • これらの基準を満たすソースコード文字列を生成できない場合、evalSyntaxError例外をスローする文字列を返す必要があります。

あなたはMethodDefinitionを持っているので、あなたは、メソッドの表現を取得。 MethodDefinitionでもでもないGeneratorMethodの関数がある場合は、eval(3番目のポイント)になる表現が得られる可能性がありますが、その場合でも実装はスローされる表現を返す必要があります構文エラーです。¯\_(ツ)_/¯

+0

これは現在のケースですが、これに基づいています:http://tc39.github.io/Function-prototype-toString-revision/#sec-function.prototype.tostring、これは(近い将来の) – Drax

関連する問題