問題における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のセキュリティ構成と検出

推薦する

角度に基づくツリー型セカンダリテーブルを実現する

まず効果を見てみましょう: コード: 1.html <div class="user...

MySQL テーブルの読み取り、書き込み、インデックス作成、その他の操作の SQL ステートメントの効率最適化の問題を分析します。

前回は、Explain 実行プランの表示、インデックスの分析など、MySQL での SQL クエリの...

JavaScript の 50 以上のユーティリティ関数の概要

JavaScript は多くの素晴らしい機能を備えています。この記事では、作業効率の向上とコードのデ...

JavaScriptの再帰の詳細

目次1. 再帰とは何ですか? 2. 再帰を使って数学の問題を解く1. 1 * 2 * 3 * 4 …...

HTML知識ポイントの実践経験のまとめ

1. 表タグはtable、trは行、tdはセル、cellspacingはセル間の距離、cellpad...

WeChatアプレットはシンプルなチャットルームを実装します

この記事では、WeChatアプレットの具体的なコードを共有し、簡単なチャットルームを実装します。具体...

ベスト HTML/CSS デザインおよび開発フレームワーク 15 選を紹介します

プロフェッショナルな Web デザインは複雑で時間がかかります。 HTML と CSS フレームワー...

MySQL 高可用性クラスタの展開とフェイルオーバーの実装

目次1. 内閣府1. コンセプト2. MHAの構成3. MHAの特徴2. MySQL+MHAをビルド...

ウェブページで Enter キーを押すと自動的にフォームを送信し、他のページにジャンプするソリューション

ウェブページでEnterキーを押すと、フォームは自動的に送信され、他のページに移動します。クエリフォ...

Jenkins の紹介と Docker で Jenkins をデプロイする方法

1. 関連概念1.1 Jenkins の概念: Jenkins は、使用されるプラットフォームに関係...

JavaScript イベントバブリング、イベントキャプチャ、イベント委任の詳細な説明

1. イベントバブリング: JavaScript イベント伝播のプロセスでは、要素でイベントがトリガ...

jwtを使用してノードによって生成されたトークンをどこに保存するかについての簡単な説明

A: 通常はクライアントに保存されます。 jwt または JSON Web Token は、リクエス...

MySQL ステートメントを使用した簡単な追加、削除、変更、クエリ操作の例

この記事では、例を使用して、MySQL ステートメントを使用して、単純な追加、削除、変更、およびクエ...

全文検索とキーワードスコアリング方式のMySQL実装例

1. はじめに今日、同僚から、MySQL を使用して ElasticSearch に似た全文検索機能...