問題は、誰もが「メモリ リーク」について知っていることです。一般的なシナリオはいくつかあります。
ポイント 3 は私の注意を引きました。その意味はよくわかります。たとえば、「DOM ノードを手動で削除し、DOM ノードが占有していたメモリを解放する必要があるが、不注意により、一部のコードに削除されたノードへの参照が残っているため、最終的にノードが占有していたメモリが解放されない」とします。 <div id="ルート"> <div class="child">私は子要素です</div> <button>削除</button> </div> <スクリプト> btn = document.querySelector('button') とします。 child = document.querySelector('.child') とします。 root = document.querySelector('#root') とします。 btn.addEventListener('クリック', 関数() { root.removeChild(子) }) </スクリプト> このコードは、ボタンをクリックした後に .child ノードを削除します。クリック後にノードは確かに DOM から削除されますが、グローバル変数 child にはまだノードへの参照があるため、ノードのメモリを解放できません。 解決策: .child ノードへの参照をクリック イベントのコールバック関数に移動できます。その後、ノードが削除され、コールバック関数が終了すると、ノードへの参照は自動的にクリアされ、当然メモリ リークは発生しません。 (これは実際にはイベント内にノードが存在するかどうかをリアルタイムで検出するものです。存在しない場合、ブラウザは削除関数の実行をトリガーしません。) <div id="ルート"> <div class="child">私は子要素です</div> <button>削除</button> </div> <スクリプト> btn = document.querySelector('button') とします。 btn.addEventListener('クリック', 関数() { child = document.querySelector('.child') とします。 root = document.querySelector('#root') とします。 root.removeChild(子) }) </スクリプト> このコードは完璧ですか?いいえ。各イベントがトリガーされた後に、子ノードとルートノードへの参照が作成されるためです。メモリ消費量(気が狂いそうな人もいるだろう ボタンのクリック…)。 実際には、別の方法があります。クリック時に、現在のルート ノードに子ノードがまだ存在するかどうかを判断します。存在する場合は、削除関数を実行し、存在しない場合は何もしません。 これにより、タイトルに記載されている動作が発生します。 どう判断する? トラバース?いや、面倒すぎるよ! どういうわけか、プロトタイプ チェーンに基づいてオブジェクトを走査できる 当時のシーンを復元してみましょう。GitHub を開き、親ノードをランダムに探して取得します。 図の赤い枠は取得したい親要素、オレンジ色の枠は存在するかどうかを判定したい子要素です。 親を document.querySelector('.position-relative') とします。 子を document.querySelector('.progress-pjax-loader') にします。 ここで、取得するのは DOM ノード (配列のようなオブジェクト) であるため、操作の前に処理する必要があることに注意してください。 p_child=[...parent.children]とします。 それから console.log(p_child 内の子); ! ! ! なぜ? (この時点では、筆者はまだ事の重大さに気づいていない) 何か問題があったのではないかと思い、es6 の include API を使用して確認しました。 console.log(p_child.includes(child)); それは正しい! 通常の配列で検証してみましょう。 ? ? ? この時点で、MDN を確認することを思い出しました。 その後、次のことがわかりました。in 演算子を単独で使用すると、左側の値 (インデックスとして) に対応する値が右側のオブジェクト (プロパティとプロトタイプ) 内にあるかどうかが検出されます。 上記のコードに戻ると、次のことがわかります。 これは私たちの結論を裏付けています。 明らかに、「子要素」は「プロトタイプ チェーン上に存在する」ことと同じではありません。これは、属性とプロパティの違いという別の知識ポイントにつながります。 したがって、いくつかの「トラブル」の後、ソース コードは次のように直接記述する必要があります。 <div id="ルート"> <div class="child">私は子要素です</div> <button>削除</button> </div> <スクリプト> btn = document.querySelector('button') とします。 child = document.querySelector('.child') とします。 root = document.querySelector('#root') とします。 r_child = [...root.children] とします。 btn.addEventListener('クリック', 関数() { if(r_child.includes(child)){ // または、child が null かどうかを確認することもできます... root.removeChild(child) } }) </スクリプト> やや急ぎの結末 だから、読書や勉強は「徹底的に理解しようとしない」というわけにはいかないのです~ また、「面倒なことをする」勇気と、「書類を確認する」方法を学ぶ勇気も必要です [/ 面白い顔]。 要約する 問題の JS 演算子に関するこの記事はこれで終わりです。問題の JS 演算子に関する詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Alibaba Cloud で MySQL リモート接続を構成するための詳細な手順
>>: ウェブサイトがhttpsを有効にした後のSSLのセキュリティ構成と検出
1. Nginx サービス基盤Nginx (エンジン x) は、パフォーマンスの最適化のために特別...
1. はじめに少し前、開発者がテスト環境や本番環境で誤った操作をし、データベースを誤って削除/更新し...
1. docker-maven-pluginの紹介私たちの継続的インテグレーションプロセスでは、プロ...
この記事では、二次リンク効果を実現するためのReact+tsの具体的なコードを参考までに共有します。...
1. 準備1.1 VMware 15 をダウンロードしてインストールするダウンロード リンク: h...
概要リレーショナル データベースでは、インデックスは、データベース テーブル内の 1 つ以上の列の値...
HTML Web ページ リスト タグの学習チュートリアル。 HTML ページでは、リストはアウトラ...
GNU Parallel は、1 台以上のコンピューター上で計算タスクを並列に実行するためのシェル ...
序文リレーショナル データベースは、システムのボトルネックになる可能性が高くなります。単一のマシンの...
1. コマンドの紹介usermod (ユーザー変更) コマンドは、ユーザー アカウントを変更するため...
この記事では、MySQL を使用してデータを Excel にエクスポートする方法について説明します。...
まずSQLを書く SELECT DISTINCT from_id タラから cod.from_id ...
使用シナリオ: Alibaba Cloud を使用しており、データディスクを別途購入しました (大容...
この記事では、シンプルなカレンダー効果を実現するためのjsの具体的なコードを参考までに共有します。具...
この記事では、参考までに、シンプルなページカウントダウンを実装するためのJavaScriptの具体的...