問題におけるJS演算子の調査

問題におけるJS演算子の調査

問題は、誰もが「メモリ リーク」について知っていることです。一般的なシナリオはいくつかあります。

  • クロージャの不適切な使用はメモリリークを引き起こす
  • (宣言されていない)グローバル変数
  • 分離されたDOMノード
  • (オプション) コンソールへの出力
  • 忘れられたタイマー
  • 循環参照

メモリ リークは深刻に受け止める必要があります。メモリ リークは非常に深刻で、ページがフリーズしたり、ユーザー エクスペリエンスに影響したりすることもあります。

ポイント 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(子)
    })

</スクリプト>

このコードは完璧ですか?いいえ。各イベントがトリガーされた後に、子ノードとルートノードへの参照が作成されるためです。メモリ消費量(気が狂いそうな人もいるだろう

ボタンのクリック…)。

実際には、別の方法があります。クリック時に、現在のルート ノードに子ノードがまだ存在するかどうかを判断します。存在する場合は、削除関数を実行し、存在しない場合は何もしません。

これにより、タイトルに記載されている動作が発生します。

どう判断する?

トラバース?いや、面倒すぎるよ!

どういうわけか、プロトタイプ チェーンに基づいてオブジェクトを走査できるfor...inin 演算子を突然思いつきました。

当時のシーンを復元してみましょう。GitHub を開き、親ノードをランダムに探して取得します。

マイ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 演算子を単独で使用すると、左側の値 (インデックスとして) に対応する値が右側のオブジェクト (プロパティとプロトタイプ) 内にあるかどうかが検出されます

上記のコードに戻ると、次のことがわかります。

証明_2

これは私たちの結論を裏付けています。

明らかに、「子要素」は「プロトタイプ チェーン上に存在する」ことと同じではありません。これは、属性とプロパティの違いという別の知識ポイントにつながります。

したがって、いくつかの「トラブル」の後、ソース コードは次のように直接記述する必要があります。

<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 をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript における typeof および instanceof 演算子の使用に関する議論

<<:  Alibaba Cloud で MySQL リモート接続を構成するための詳細な手順

>>:  ウェブサイトがhttpsを有効にした後のSSLのセキュリティ構成と検出

推薦する

Linux でタスク用のカスタム システム トレイ インジケーターを作成する

システム トレイ アイコンは、今日でも魔法のような機能です。アイコンを右クリックして目的のアクション...

nginxプロセスロックの実装の詳細な説明

目次1. nginxプロセスロックの役割2. エントリーレベルのロックの使用3. nginxプロセス...

MySQLデータファイルの保存場所を表示する方法

次のような疑問が湧くかもしれません。MySQLをローカル (自分のコンピュータ) にインストールした...

HTML webpackプラグインの使用に関する簡単な分析

html-webpack-pluginプラグインを使用してページを開始すると、htmlページをメモリ...

ノードの対応するバージョンに関する簡単な説明 node-sass sass-loader

目次ノードのバージョンが一致しない、ノードをアップグレードまたはダウングレードするnvm を使用して...

MySql インデックス使用戦略の分析

MySql インデックスインデックスの利点1. 一意のインデックスまたは主キー インデックスを作成す...

Vue要素はテーブルの追加、削除、データの変更を実装します

この記事では、テーブル内のデータを追加、削除、変更するためのvue要素の具体的なコードを参考までに共...

Vue3 の ref toRef と toRefs の違いを理解する方法

目次1. 基本1.参照2. 参照3. 参照4. 最適な使い方2. 詳細な1. なぜrefが必要なのか...

MySQL 5.7.20 解凍版のインストールとルートパスワードの変更に関するチュートリアル

1. MySQL アーカイブ (解凍版) をダウンロードするURL: https://downloa...

MySQL に 1,000 万件のレコードを素早く挿入する方法

面接で「MySQL に 1,000 万件のレコードをすばやく挿入するにはどうすればよいか」という質問...

html.cssオーバーフローの包括的な理解

html.cssオーバーフローの包括的な理解XML/HTML コードコンテンツをクリップボードにコピ...

Docker+K8S クラスタ環境構築と分散アプリケーション展開

1. Dockerをインストールする yumでdockerをインストール #サービスを開始する sy...

js QRコードスキャンログインの原理についての簡単な説明

目次QRコードログインの真髄QRコードを理解するシステム認証メカニズムQRコードをスキャンしてログイ...

HTML要素にフォーカスを設定する方法

コードをコピーコードは次のとおりです。 <本文<フォームアクション="&quo...

Vue は無限ロードウォーターフォールフローを実装します

この記事では、参考までに、無限ロードウォーターフォールフローを実現するためのVueの具体的なコードを...