0

以下のコードがこれを正しく返さないのはなぜですか? オブジェクト内のすべての文字ではなく、単に「画像」を返す必要がありますね。

String.prototype.removeExtension = function(){
    return (this.lastIndexOf('.') !== -1) ? this.substr(0, this.lastIndexOf('.')) : this;
}

'image.jpg'.removeExtension(); // returns 'image'

'image.png.jpg'.removeExtension(); // returns 'image.jpg'

'image'.removeExtension(); // returns String {0: "i", 1: "m", 2: "a", 3: "g", 4: "e", removeExtension: function}
4

3 に答える 3

2

this常にスコープ(*)のコンテキスト内でオブジェクトを参照します。たとえば、疑似プリミティブ値を取得するには、呼び出す必要があります。.toString()

return this.toString();

そのように戻ると、現在呼び出されthisているインスタンスの現在のインスタンスが参照されます。String-object


(*) (唯一の例外は ES5 strict モードで、値thisを参照する場合もありますundefined

于 2013-04-01T13:00:36.073 に答える
0

プリミティブ文字列値Stringオブジェクトには違いがあります。

'foo'             // primitive

new String('foo') // object

文字列プリミティブで String メンバー関数を呼び出すと、関数内の値になる String オブジェクトにラップされthisます。(この動作については、以下で詳しく説明します。)

したがって、 inremoveExtensionはオブジェクトですthisString一方、組み込み関数this.substrはプリミティブを返します。それが定義されているだけです。thisしたがって、 ( String objectthis.substr ) を返すときと(string Primitive )の結果を返すときは、異なることがわかります。オブジェクトの文字列プリミティブ バージョンを返したい場合はthis、単にthis.toString.

Numbersなどのどのプリミティブでも同じラッピング動作が見られます。

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

typeof 2;               // 'number'
typeof (2).returnThis() // 'object' (a Number object, specifically)

なぜこれが起こるのか本当に知りたい場合は、ECMAScript 仕様にあります。

10.4.3 機能コードの入力

関数オブジェクト F に含まれる関数コードの実行コンテキストに制御が入ると、次の手順が実行されます。

  1. 機能コードが厳格なコードの場合は、 を に設定ThisBindingthisArgます。
  2. それ以外の場合、thisArg が null または未定義の場合はThisBinding、グローバル オブジェクトに設定します。
  3. Type(thisArg)が Object でない場合は、 を に設定ThisBindingToObject(thisArg)ます。
  4. ....

ポイント #3 が重要です。プリミティブ値 (つまり、非オブジェクト) で関数を呼び出すと、対応するオブジェクト形式に変換されます。

于 2013-04-01T13:08:22.840 に答える
0

String は char 配列ではないため、これは正常な動作です。そう

'image'.removeExtension();

{0: "i", 1: "m", 2: "a", 3: ... ではないオブジェクト文字列を返します。

特定の文字を取得するには、'image'.charAt(3); を使用します。// g

于 2013-04-01T13:15:15.800 に答える