2012-05-10 12 views
5

私は、javascriptで関数プロトタイプを拡張できるようになっています(つまり、すべての関数に関数を追加しています)。 目的は、別の言語(すなわち、この特定の設定では文字列を介してのみ通信できるruby)間の交換用の形式に変換することです。 Iこれは、他のすべてのために働いているので、関数プロトタイプを拡張する

Number.prototype.to_ruby = function() { return this.toString(); } 

のように私はそれがしたい私は、RubyのオブジェクトとJavaScriptオブジェクトのto_ruby法上to_js方法を定義することで、他の種類の周りに渡すことができるように、既にシステムを持っています、関数用ではありません。

_empty = function() {}; 
_empty.__proto__.to_ruby = function() { 
    return 'JSFunction.new(' + this.toString().to_ruby() + ')'; 
}; 

しかし、これは(システムの要件である)IEでは動作しません:私は、それは次の操作を行って、クロームで動作するように取得することができます。

私はIDのような機能のトラックをどこかに保持しているオブジェクトがあると知っていますが、それらを作成した同じインスタンスで使用されることは保証できません。

すべての他の失敗私はちょうどそれとの特別なケースとの契約(すなわち、isFunction(instance) ? fn_to_ruby(instance) : instance.to_ruby()に関数を書くこともできますが、可能であれば、私はむしろ、このモデルを維持するだろう。

+0

ハァ!私はちょうど同じことを調べていることがあります。 SketchUp Ruby <-> JavaScriptブリッジ。 :D – thomthom

答えて

2

__proto__は標準のプロパティではありません。このアプローチを試してみてください:

(function(){}).constructor.prototype.to_ruby = function(){ 
    return 'JSFunction.new(' + this.toString().to_ruby() + ')'; 
}; 
+0

ああ! '.constructor'を追加すると、私が探していた機能が得られます - ありがとう! – DanielB

+2

あなたはキャラクターによって支払われなければなりません。 '(function(){})。constructor.prototype'は単に' Function.prototype'です。 'someObj.to_ruby()'を呼び出すことは '+" someobj'と同じになります。 – RobG

+0

@RobG、あなたは正しかった - もちろん私はそれを見ることができます。ありがとう:) – DanielB

-1

__proto__それだけだ任意のJavaScriptの標準の一部ではありませんpesudo標準のブラウザメーカーのいくつかは、実装することを決めたこと。IEはがそれを実装していないということです。

あなたがJavaScriptの型システムにあらゆるタイプを変更したい場合は、あなたが持っているでしょうObjectプロトタイプを変更するには

Object.prototype.foo = function() { console.log('foo'); }; 
(1).foo(); 
'asd'.foo(); 
(true).foo(); 
({ bar: 'baz' }).foo(); 
3

SlaceあなたがObject.prototypeにそれを追加することによって、すべてのオブジェクトにメソッドを追加することができますが、それはひどくループFOR..IN書か影響を及ぼす可能性として、それが本当にコーシャではない、言ったように。

あなたはFunction.prototype経由だけの機能に追加することができます:

Function.prototype.to_ruby = function() { 
    return this.toString(); 
} 

を使用すると、組み込みオブジェクト変更すべきではありません一般的なルールはそれを悩ませ戻ってくるとき、あなたは決して知らない主な理由は、そこにあるしかし、あなた(例えば、新しいバージョンのECMAScriptは同じ名前のプロパティを実装します)。おそらく、あなたは、単一のtoRuby機能記述するほうが良いでしょう:

function toRuby(obj) { 
    return obj.toString(); 
} 

をしかし、あなたはまた、暗黙のうちにtoStringメソッドを呼び出すために、文字列を連結し+演算子を使用することができます。

戻ります
'' + obj; // returns obj.toString() 

両方の場合とまったく同じ結果になります。あなたの選択。

+0

私はあなたの議論を理解していますが、私は、少しずつ異なって戻ってくる必要があるオブジェクトの種類がいくつかあります。 これは数字や文字列のような基本的な型(エスケープする必要はないと仮定します)では機能しますが、配列やハッシュのようなオブジェクトやカスタム型では、それぞれ特殊なケースを書いて編集を続けなければなりませんそれは私が多かれ少なかれオブジェクトを必要とするからです。 – DanielB

+0

その場合、単一の 'toRuby()'関数を記述して、渡されたオブジェクトをどのように変換するかを教えてください。 'toRuby(someFn、 'fn')'、 'toRuby(someObj、 'obj')'などと呼ばれます。 – RobG

+0

それは私が元々持っていたものですが、可能なオブジェクト型の数が増えるにつれて、変換をサポートしているオブジェクトに対してto_rubyメソッドを持たせるほうが簡単になると思いました。そうすれば、私はサポートを簡単にテストし、変換を実行することができます。 – DanielB

関連する問題