4

Stringたとえば、インスタンスにメソッドを追加することは可能ですか?

x = "123"
x.method = function() { console.log("test") }

x.method()
4

3 に答える 3

4

はい、できます。ただし、最初に文字列プリミティブを取得して文字列インスタンスにする必要があります。

x = new String("123");
x.method = function() { console.log("test") };

x.method();

JavaScript には、文字列プリミティブと文字列インスタンスの両方があります。元のコードでは、次のように記述しました。

x.method = ...;

...文字列プリミティブは変数から取得xされ、メソッドを追加した文字列インスタンスに昇格されましたが、文字列インスタンスは変数に格納されてxいないため、呼び出そうとしたときにメソッドがありませんでした. (はい、これ直感に反します。)

上記で使用new String(...)することにより、実際に文字列インスタンスを取得して に格納しxます。次に、これは適切なオブジェクトなので、プロパティを追加できます。

String.prototype次のように、にメソッドを追加することもできます。

String.prototype.capitalize = function() {
    return this.substring(0, 1).toUpperCase() + this.substring(1);
};

console.log("testing".capitalize()); // "Testing"

これは悪い習慣だと感じる人もいます。他の人は、まさにそれがプロトタイプの継承を持っている理由であり、プロトタイプを使用して物事を拡張できると言います。私は人々が を強化することによる問題を見たことがありませんが、人々が をString.prototype強化するときに問題あるようです(人々は を誤用Array.prototypeすることを主張するため) .for-inObject.prototype

于 2013-03-29T22:07:24.507 に答える
3

文字列と数値は自動ボックス化されたプリミティブです。つまり、オブジェクト指向操作を実行すると、「文字列」および「数値」クラスとしてキャストされますが、すぐにボックス化されません。

コードは次のように評価されます。

x = "123"
(new String(x)).method = function() { console.log("test") }

(new String(x)).method() // Error

まったく異なる String オブジェクトを扱っているため、2 番目の呼び出しは失敗しています。TJ が述べたように、String オブジェクトを作成することでこれを回避できますがx、これは一般的または推奨される方法ではありません。

メソッドを に追加することで、すべての文字列を拡張できますString.prototype

x = "123"
String.prototype.method = function() { console.log("test") }

x.method()

この呼び出しは と同じように評価されます(new String(x)).method()が、そのメソッドはプロトタイプに存在するため、呼び出されます。

于 2013-03-29T22:10:51.883 に答える
1

ECMA5 を使用して新しいプロパティを定義できます

Object.defineProperty(String.prototype, "test", {
value: function test() { console.log('test:',this) },
  configurable: true,
  enumerable: false,
  writeable: true
});

完全な回答を参照してください: プロトタイプを変更せずにコア タイプを拡張する

于 2013-03-29T22:38:35.440 に答える