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

推薦する

jQueryは検証コード送信のコントロールボタンを無効にする機能を実装します

必要な効果: 確認コードを送信するためにクリックした後、ボタンは無効になり、5 秒後に無効解除されま...

Vue の計算プロパティとリスナーの使用の概要

1. 計算プロパティとリスナー1.1 計算プロパティ <!DOCTYPE html> &...

モバイルプラットフォーム開発におけるメタタグの適用の詳細な説明

デスクトップ プラットフォームの Web レイアウトのメタ タグは誰もがよく知っています。これは常に...

Python で pymysql モジュールを使用して MySQL データベースに接続する

pymysqlをインストールするpip install pymysql 2|0pymysqlの使用2...

SQLはLeetCodeを実装します(180.連続した数字)

[LeetCode] 180. 連続した数字少なくとも 3 回連続して出現するすべての数字を検索す...

MySQLのマスタースレーブレプリケーションと読み取り書き込み分離を理解するための記事

目次導入1. MySQL マスタースレーブレプリケーション1. MySQLレプリケーションタイプ2....

MySQL に絵文字表現を挿入できない問題の解決方法

序文最近この問題に遭遇するまで、私は UTF-8 が文字セットの問題に対する普遍的な解決策だと考えて...

簡単な手順で純粋な CSS3 で 3D 反転効果を実現

フロントエンド開発者の必須科目であるCSS3は、多くの基本的なアニメーション効果を実現するのに役立ち...

Vue elementUI フォームのネストされたテーブルと各行の検証の詳細な説明

目次エフェクト表示コードリンクキーコード表形式データコンポーネントのネスト検証方法リセット方法完全な...

Ubuntu 上の MySQL における中国語文字化け問題の解決方法

問題を見つける最近 Django を学習しているのですが、MySQL データと組み合わせてデータを挿...

Linux での MySQL 5.6.27 インストール チュートリアル

この記事では、LinuxでのMySQL 5.6.27のインストールチュートリアルを参考までに紹介しま...

デザインストーリー: ナンバープレートを覚えられない警備員

<br />私が住んでいる地域では、コミュニティに出入りする車両を管理するために、コミュ...

CSS 画面サイズ適応実装例

CSS 画面サイズの適応を実現するには、まず CSS3 @media メディア クエリを導入する必要...

MySQL パーティションテーブルの正しい使用方法

MySQL パーティションテーブルの概要数億、あるいは数十億ものレコードを格納するテーブルに遭遇する...

Vue-Routerのインストールと使用方法の詳細な説明

目次インストールルーティングの基本構成Vue にルーターをインストールするルーターの設定Router...