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

推薦する

Ubuntu ベースのディストリビューションに Microsoft TrueType フォントをインストールするチュートリアル

Linux 上の LibreOffice で Microsoft ドキュメントを開くと、フォントが少...

Linux システムの busybox に mkfs.vfat コマンドを移植する

オーディオおよびビデオ ファイルを保存するためのディスク寿命を延ばすには、ディスクをフォーマットする...

ウェブデザイナーが持つべき7つのスキル

Web デザインは科学であると同時に芸術でもあります。 Web デザイン作業は、半分は適切なプログラ...

Windows オペレーティング システムでの Linux 仮想マシンのインストールと構成のチュートリアル

序文仕事では、Linux 環境で操作する必要があることがよくあります。ここでは、win10 システム...

中国語ウェブコンテンツを紹介する10の経験

<br /> テキスト、シンボル、リンクの 3 つの側面に焦点を当て、主に中国語で、私の...

vue3を使用して人間と猫のコミュニケーションアプレットを実装する

目次序文プロジェクトを初期化するデザインコードの実装オンデマンドロードオーディオを再生録音長押しイベ...

Linux で複数のファイルの名前を一括で変更する方法

Linux では、通常、ファイルの名前を変更するために mv コマンドを使用します。これは、単一のフ...

JSはシンプルなカウンターを実装します

HTML CSS および JavaScript を使用して、プラス、マイナス、ゼロの 3 つのボタン...

MySQLとOracleの違いのまとめ(機能性能の比較、選択、使用時のSQLなど)

1. 同時実行性同時実行性は OLTP データベースの最も重要な機能ですが、同時実行性にはリソース...

WIN10 システムと Docker 内部コンテナ IP 間の通信方法

1. Windows 版の Docker をインストールしたら、Docker クイックスタート ター...

Kylin 4.0.2 (Ubuntu) でブート パーティションを拡張するプロセスの紹介

目次序文1. 新しいパーティションを準備する2. ブートパーティションをコピーする3. fstabフ...

Linux サーバー上のローカル静的リソースにアクセスするために nginx を使用する方法

1. ポート 80 が占有されているかどうかを確認します。通常、ポート 80 は Apache サー...

HTML テーブル マークアップ チュートリアル (16): タイトルの水平方向の配置属性 ALIGN

デフォルトでは、表のタイトルは水平方向に中央揃えされます。ALIGN 属性を使用して、タイトル テキ...

CSS3 は反転可能なホバー効果を実現します

CSS3 は反転可能なホバー効果を実装します。具体的なコードは次のとおりです。 1.css /*基本...

jQueryは要素を追加した後に元のイベントが実行されない問題を解決します

まずエラーコードを見てみましょう。 html: <テーブルボーダー="1"...