1. ホーム
  2. javascript

[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?

2022-07-22 11:48:29

質問

引用元 MDN

<ブロッククオート

文字列リテラル(二重引用符または一重引用符で示される)および文字列 文字列リテラル(二重引用符で囲まれた文字列)、およびコンストラクタ以外のコンテキストで(つまり はプリミティブ文字列です。JavaScript は自動的に は自動的にプリミティブを String オブジェクトに変換します。 そのため、プリミティブな文字列に対してStringオブジェクトのメソッドを使うことができます。そのため メソッドがプリミティブな文字列に対して呼び出されたり、プロパティの検索が行われるような場面では が発生する場合、JavaScript は自動的に文字列プリミティブをラップして メソッドを呼び出したり、プロパティを参照したりします。

で、文字列プリミティブに対する操作(メソッド呼び出し)は、文字列オブジェクトに対する操作よりも遅くなるはずだと(論理的に)考えていました。なぜなら、文字列プリミティブはすべて method が適用される前に文字列Objectに変換されるからです。

しかし、この テストケース では、結果は逆になっています。その コードブロック-1 よりも速く実行されます。 コードブロック-2 の方が高速に動作します。

コードブロック-1 :

var s = '0123456789';
for (var i = 0; i < s.length; i++) {
  s.charAt(i);
}

コードブロック-2 :

var s = new String('0123456789');
for (var i = 0; i < s.length; i++) {
    s.charAt(i);
}

結果はブラウザによって異なりますが コードブロック-1 は常に高速です。どなたかこれを説明していただけませんか? コードブロック-1 よりも速いのか。 コードブロック-2 .

どのように解決するのですか?

JavaScriptには、プリミティブとオブジェクトという2つの主要な型カテゴリがあります。

var s = 'test';
var ss = new String('test');

シングルクォート/ダブルクォートのパターンは、機能的には同じです。それはさておき、あなたが名付けようとしている動作はオートボックスと呼ばれるものです。つまり、実際に起こることは、プリミティブはラッパー型のメソッドが呼び出されたときに、そのラッパー型に変換される、ということです。簡単に言うと

var s = 'test';

プリミティブなデータ型です。メソッドを持たず、生データのメモリ参照へのポインタに過ぎず、ランダムアクセスの速度がはるかに速いのはこのためです。

では、次のようにするとどうなるでしょうか。 s.charAt(i) のようになるのでしょうか?

では s のインスタンスではないので String のインスタンスではない場合、JavaScript は自動ボックス化されます。 s を持ちますが、これは typeof string をラッパーの型に変換します。 String を持つ typeof object より正確には s.valueOf(s).prototype.toString.call = [object String] .

オートボックスの動作は s を必要に応じてラッパー型にキャストしますが、より単純なデータ型を扱っているため、標準的な操作は信じられないほど高速です。しかし、オートボクシングと Object.prototype.valueOf は異なる効果を持ちます。

自動ボックス化を強制したい場合、あるいはプリミティブをラッパーの型にキャストしたい場合は Object.prototype.valueOf を使うことができますが、動作は異なります。様々なテストシナリオに基づき、自動ボックス化は、変数のプリミティブな性質を変えることなく、「必要な」メソッドを適用するだけです。これが、より良い速度を得る理由です。