質問は自明です。などのプリミティブ データ型を拡張できることはわかっていますstring
が、上書きすることはできますか?
これはインタビューで尋ねられた質問です。
いいえ、何も上書きできません。EcmaScriptは、プリミティブ型 Undefined
、、、、およびを定義します。これらは内部的なものであり、何をしているかに関係なく使用されます (たとえば、グローバルコンストラクターの上書きなど)。リテラルの型変換と評価はパブリック関数に依存せず、これらの内部型とそれらに指定されたアルゴリズムのみを使用します。Null
Boolean
Number
String
String
もちろん、誰かがグローバル変数String(myval)
に代入する代わりに文字列強制を行うと、そのコードに影響を与えます。内部使用は依然として「古い」関数を指します。""+myval
String
プリミティブ型 ( object として使用される場合)のプロトタイプ オブジェクトについて話していた場合、それらも上書き可能ではありません。これらのオブジェクトを拡張することはできますが、たとえばに割り当てるとすぐNumber.prototype
に、実際の元の数値プロトタイプ オブジェクトへの参照が失われます。The Number コンストラクターの仕様例:
新しく構築されたオブジェクトの [prototype] は、( 15.7.3.1 )の初期値である元のNumber プロトタイプ オブジェクトに設定されます。
Number.prototype
はい(編集:ほぼ)。Javascript コンソール (Chrome を使用している場合は F12) を開き、次のように入力します。
String = function(){alert('bang!')};
Javascript のすべてを上書き (編集: ほとんどwindow
) できます —グローバル コンテキストでさえも! Evil.jsは、このトリックを使用して多くのネイティブ オブジェクトを可能な限り書き換えるライブラリです。
言うまでもなく、これは非常に危険です。上記の再マッピング コードを実行しましたString
が、それを書き留めてから、520 以上の Javascript エラーが発生しました (そして、'bang' というアラートが何度も表示されました)。ネイティブ オブジェクトはどこでも使用されており、サード パーティのコードが不明な方法でネイティブ オブジェクトに依存している場合に備えて、これらを変更しないでください。これが、Prototype.js が人気を失った理由の 1 つです。ネイティブ オブジェクトの拡張が、他のコードの期待に反することが多いためです。
編集: Bergiの回答で指摘されているように、絶対にすべてが上書きされる可能性があるという、事実上正しくない主張です。編集はインラインで行われました。
ネイティブ型のプロトタイプを拡張できます。
String.prototype.moo = function() {
console.log( 'Moo!' )
};
'Cow says'.moo();
>> "Moo!"
ただし、オブジェクト全体への参照を上書きしない限り、組み込み型のコンストラクターを直接上書きすることはできません。
String = function() {
console.log( 'Custom function.' )
};
new String( 'Hello!' );
>> "Custom function."
>> String {} // now you've broken your website ;)
...それでも:
'Wat?!'
>> "Wat?!" // you can still create strings by typing letters in quotes
だから...答えは「はい、いいえ」です。Number
ネイティブ型 ( 、Date
、 ...)を台無しにすることはできString
ますが、最初から完全に再定義することはできません。これらは、使用している JS エンジン (ほとんどの場合ネイティブ C++ コード) の一部であり、これによりいくつかの制限が生じます。
このように可能ですが、常に副作用なしで成功する必要があります。良い習慣ではありません。
function Array() {
var obj = this;
var ind = 0;
var getNext = function(x) {
obj[ind++] setter = getNext;
if (x) alert("Data stolen from array: " + x.toString());
};
this[ind++] setter = getNext;
}
var a = ["private stuff"];
// alert("Data stolen from array: private stuff");