---- 非基本型の基本型 この質問を見ると、この質問はあまりにも基本的なものであり、これ以上基本的なことはできないと誰もが感じると思います。 Baidu で検索すると、基本型はスタックに格納され、参照型はヒープに格納されると言っている人がたくさんいることがわかります。 本当にそんなに簡単なのでしょうか? 1. 冷蔵庫に入りきらない象次のコードを見てみましょう: ここでは 67MiB の文字列を宣言していますが、文字列が実際にスタック上に存在していた場合、これを説明するのは困難です。結局のところ、v8 のデフォルトのスタック サイズは 984KiB です。絶対に救えない。 注: V8 では、オペレーティング システムによって、また時期によって、文字列サイズの制限が異なります。おおよその範囲は256MiB~1GiBです node --v8-options | grep -B0 -A1 スタックサイズ この時点で、疑問に思い始めていますか? Baidu からの回答が間違っていて、Google で検索する必要がある可能性はありますか? 何が起こっているのか見てみましょう。 2. シャドウクローン文字列const BasicVarGen = 関数(){ this.s1 = 'IAmString' this.s2 = 'IAmString' } a = 新しい BasicVarGen() とする b = 新しい BasicVarGen() とする ここでは、それぞれ 2 つの同一の文字列を含む 2 つの同一のオブジェクトを宣言します。 開発者ツールを使用すると、4 つの文字列を宣言したにもかかわらず、それらのメモリが同じアドレスを指していることがわかります。 注: これはどういう意味ですか? 4 つの文字列に参照アドレスが含まれていることがわかります。 なので、上記の記事の冷蔵庫に入りきらない象は簡単に説明できます。文字列はスタックに格納されるのではなく、別の場所に格納され、その場所のアドレスがスタックに格納されます。 そこで、文字列の 1 つの内容を変更してみましょう。 const BasicVarGen = 関数(){ this.s0 = 'IAmString' this.s1 = 'IAmString' } a = 新しい BasicVarGen() とする b = 新しい BasicVarGen() とする デバッガ a.s0 = '異なる文字列' a.s2 = 'IAmString' a.s0 の初期コンテンツは ' 新しく追加された a.s2 の内容は ' 文字列を宣言する場合:
では、整理してみましょう。文字列を作成すると、V8 はまずメモリ (ハッシュ テーブル) を検索して、すでに作成されている同一の文字列があるかどうかを確認します。存在する場合は、直接再利用されます。存在しない場合は、文字列を格納するための新しいメモリ領域が開かれ、そのアドレスが変数に割り当てられます。これが、添え字を使用して文字列を直接変更できない理由です。V8 の文字列は不変です。 jsの基本型コピーを例に、v8の実装ロジックと誰もが理解している従来のロジックを説明します(Yawen) 例: var a = "刘潇洒"; // V8 は文字列を読み込んだ後、stringTable にアクセスして文字列が存在するかどうかを確認します。存在しない場合は、'刘潇洒' を hashTable に挿入し、'刘潇洒' の参照を var b = a; // '刘潇洒' の参照を直接コピーします b = "谭雅文"; // stringTable にエントリがないか検索します 質問: const BasicVarGen = 関数(){ this.s0 = 'IAmString' this.s1 = 'IAmString' } a = 新しい BasicVarGen() とする b = 新しい BasicVarGen() とする デバッガ a.s0 = '異なる文字列' a.s2 = 'IAmString' a.s3 = a.s2+a.s0; // 質問: 文字列の連結ではどのような操作が実行されますか? a.s4 = a.s2+as 同じ内容の連結された文字列を 2 つ同時に適用します。 ご覧の通り内容は同じです。しかし、住所は同じではありません。さらに、住所の前の地図の説明も変更されました。
これが文字列に当てはまる場合、他のプリミティブ型にも当てはまるでしょうか? 3. 実際に見た「奇妙なボール」文字列について説明した後、V8 のもう 1 つの典型的な「基本型」である もう一つの小さな実験をしてみましょう: 上図に基本的なタイプがリストされており、アドレスは同じであることがわかります。値を割り当てると、その値もその場で再利用されます。 (そして、 確認するためにソースコードを見てみましょう。 さまざまな オフセットが定義される場所 4. 紛らわしい数字紛らわしい番号と言われる理由は、割り当て時と変更時のメモリ割り当ての仕組みがまだ解明されていないためです。 (メモリは動的です) V8 では、数値は 最下位ビットは、それがポインターであるかどうかを示すために使用されます。最下位ビットが 1 の場合、それはポインターです。 定数o = { x: 42, // スミ y: 4.2, // ヒープ番号 }; ox の 42 は Smi として扱われ、オブジェクト自体に直接格納されますが、oy の 4.2 は追加のメモリ エンティティに格納する必要があり、oy のオブジェクト ポインターはメモリ エンティティを指します。 32 ビット オペレーティング システムの場合は、32 ビットを使用して smi を表すのは理解できますが、64 ビット オペレーティング システムでは、smi の範囲も -2³¹ から 2³¹-1 (2³¹≈2*10⁹) になるのはなぜでしょうか。 定数サイクル制限 = 50000 console.time('ヒープ番号') 定数 foo = { x: 1.1 }; (i = 0; i < cycleLimit; ++i とします) { // 追加の heapNumber インスタンスを作成します foo.x += 1; } console.timeEnd('heapNumber') // 遅い コンソール時間('smi') 定数バー = { x: 1.0 }; (i = 0; i < cycleLimit; ++i とします) { バー.x += 1; } console.timeEnd('smi') // 高速 質問: const BasicVarGen = 関数(){ smi1 = 1 です .smi2 = 2 です this.heapNumber1 = 1.1 this.heapNumber2 = 2.1 } foo = 新しい BasicVarGen() を作成します。 bar = 新しい BasicVarGen() を作成します。 デバッガ baz.obj1.heapNumber1++ 数字では、単一の数字の値は変更されませんが、他の数字のアドレスが変更されます。 5. まとめ: 基本型はどこに存在するのか?文字列:ヒープ内に存在し、スタック内の参照アドレスです。同じ文字列が存在する場合、参照アドレスは同じです。 数値:小さな整数はスタックに格納され、その他の型はヒープに格納されます。 その他のタイプ:エンジンが初期化されるときに一意のアドレスが割り当てられ、スタック内の変数には一意の参照が格納されます。 ここでは、基本的なタイプがどこに存在するかを大まかに説明するだけです。 これで、メモリの原理の詳細と、JS の変数がヒープまたはスタックに格納されるかどうかに関するこの記事は終了です。JS の変数がヒープまたはスタックに格納されるかどうかの詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: Mysql の読み取り/書き込み分離期限切れに対する一般的な解決策
張新旭氏の記事を引用して皆さんにシェアしたいと思います。 変更を加えたい場合は、対応する画像によって...
以下のように表示されます。昨日: UNIX_TIMESTAMP(CAST(SYSDATE() AS ...
目次効果のデモンストレーション:メインJSコード実装 <div class="box...
キャンバスを使用して、参照用の影付きのグラフィックとテキストを作成します。具体的な内容は次のとおりで...
1. mysqldump の使用時にエラー (1064) が報告されます。これは、mysqldump...
テーブル タグの frame 属性と rules 属性は境界線の表示を制御できます。フレーム プロパ...
vue-cli で構築されたプロジェクト スキャフォールディングでは、すでに autoprefix...
目次新しいユーザーを作成する新規ユーザーを承認する新規ユーザーのSSHキーログインを有効にする他のS...
特記事項: Swoole 拡張機能のみがインストールされ、サーバーはホストにインストールされません。...
任意の数のステートメントを関数を通じてカプセル化することができ、いつでもどこでも呼び出して実行できま...
目次サイクル比較使用法要約するサイクル比較ヴュー2ヴュー3作成前設定作成された設定マウント前マウント...
目次1. ラベルステートメントの紹介2. ラベルステートメントの使用序文:日常の開発では、プログラム...
MySQL ログ システムで最も重要なログは、REDO ログとアーカイブ ログです。後者は MySQ...
最近のウェブサイトのほとんどはページが長く、4 画面または 5 画面の長さのものもあれば、2 画面ま...
axiosをインストールして通信を実装するここでは、axios を使用して Vue フロントエンドと...