2017-01-11 11 views
5

私はDSLを構築しています。これは、JSの内部構造をハックすることができるというメリットがあります。私はこれが一般的なJSの使用法では非常に悪い考えであると理解していますが、私の目的のためには大丈夫です。次のコードは正常に動作します:JavaScriptの `String.prototype.valueOf`を置き換える

var str = new String("blah"); 
str.valueOf = function() { return 10 } 
console.log(str * 10); // outputs 100 

しかし、これはしていません:

var str = "blah"; 
str.valueOf = function() { return 10 } 
console.log(str * 10); // outputs NaN (because str === "blah") 

内部を理解し、誰かが少しここで何が起こっているか説明できますか?これら2つの例の根本的な違いは何ですか?

それでは、文字列プロトタイプ自体を変更したい場合、valueOfメソッドをのすべての文字列に設定することができます。これは可能ですか?残念ながら、これは動作していないよう:

String.prototype.valueOf = function() { return 10 } 
console.log("blah" * 10); // NaN 

これがするけど:

String.prototype.valueOf = function() { return 10 } 
console.log(new String("blah") * 10); // 100 

なぜJSエンジンは異なっ"blah"new String("blah")を扱うん:

String.prototype.valueOf = function() { return 10 } 
console.log("blah".valueOf() * 10); // 100 

そしてそうで、このしていますか?ありがとう!

ちなみに、here is a good articleそのようなものは私にこのようなものを探求させました。

答えて

5

あなたは

var str = "blah"; 

を行うと、あなたが文字列にプリミティブを作成しているが、あなたは

var str = new String("blah"); 

を行うときに、コンストラクタを呼び出し、文字列オブジェクトを作成しています。

オブジェクトがある場合、そのオブジェクトをプリミティブを挿入する場所で使用しようとすると、javascriptは内部でvalueOfを呼び出します。

プリミティブの場合、メソッドにチェーンできるようにするには逆ですが、javascriptにはオブジェクトが必要です。プリミティブでオブジェクトメソッドを呼び出すときは、内部プリミティブはnew Stringでラップされます。あなたは、文字列プリミティブ持っている、とあなたはstr.valueOfを呼び出すしようとすると、それはvalueOfを呼び出し、値を返す前に、言い換えれば

、Javascriptを内部new String(str)を行います。
しかし、文字列direclyを使用しようとすると、まだプリミティブがあり、valueOfは呼び出されません。プリミティブ値はdireclyに挿入されます。 MDN

JavaScriptが Stringオブジェクトと 原始文字列値を区別

noteから

。 (BooleanNumbersについても同様です。)

及びストリング (すなわち、 なしnewキーワードを用いた非コンストラクタコンテキストString呼び出しから返された二重または一重引用符で示される文字列リテラル())プリミティブ文字列です。それは原始的な文字列の Stringオブジェクトのメソッドを使用することができますように

JavaScriptが自動的に 、Stringオブジェクトにプリミティブに変換します。 方法は が発生した原始文字列またはプロパティの検索に呼び出されるコンテキストで

、JavaScriptが自動的にメソッドを呼び出すか、プロパティ検索を実行プリミティブと 文字列をラップします。

+0

"メソッドがプリミティブ文字列またはプロパティルックアップで呼び出されるコンテキストでは、JavaScriptは自動的に文字列プリミティブをラップし、メソッドを呼び出したりプロパティルックアップを実行します。 - 非常に卑劣です!しかしそれは理にかなっています。素晴らしい答え、感謝:) – JoeRocc

関連する問題