An exploration of the JS operator in problem

An exploration of the JS operator in problem

Here's the thing: Everyone knows about "memory leaks". It has several common scenarios:

  • Improper use of closures causes memory leaks
  • (Undeclared) global variables
  • Detached DOM nodes
  • (Optional) Printing to the console
  • Forgotten Timer
  • Circular References

Memory leaks need to be taken seriously. They are so serious that they can even cause page freezes and affect user experience!

Point 3 caught my attention. I know clearly what it means, for example: "Suppose you manually remove a DOM node, and the memory occupied by the DOM node should be released, but due to negligence, some code still has a reference to the removed node, which eventually causes the memory occupied by the node to not be released."

<div id="root">
    <div class="child">I am a child element</div>
    <button>Remove</button>
</div>
<script>
    let btn = document.querySelector('button')
    let child = document.querySelector('.child')
    let root = document.querySelector('#root')
    
    btn.addEventListener('click', function() {
        root.removeChild(child)
    })

</script>

What this code does is to remove the .child node after clicking the button. Although the node is indeed removed from the DOM after clicking, the global variable child still has a reference to the node, so the memory of the node cannot be released.

Solution : We can move the reference to the .child node to the callback function of the click event. Then, when the node is removed and the callback function is exited, the reference to the node will be automatically cleared, and there will naturally be no memory leak. (This is actually a real-time detection of whether the node exists in the event. If it does not exist, the browser will not trigger the execution of the remove function.)

<div id="root">
    <div class="child">I am a child element</div>
    <button>Remove</button>
</div>
<script>
    let btn = document.querySelector('button')

    btn.addEventListener('click', function() {  
        let child = document.querySelector('.child')
        let root = document.querySelector('#root')

        root.removeChild(child)
    })

</script>

Is this code perfect? No. Because it creates references to the child and root nodes after each event is triggered. Memory consumption (you can imagine some people going crazy

Button clicks…).

In fact, there is another way: we determine in click whether there is still a child node in the current root node. If so, execute the remove function, otherwise do nothing!

This leads to the behavior mentioned in the title.

How to judge?

Traverse? No, it's too much trouble!

Somehow, I suddenly thought of the in operator in for...in , which can traverse objects based on the prototype chain!

Let's restore the scene at that time: open GitHub, find a parent node at random, and get it:

mygithub

The red frame in the picture is the parent element we want to obtain, and the orange frame is the child element we want to determine whether it exists.

let parent = document.querySelector('.position-relative');
let child = document.querySelector('.progress-pjax-loader');

Note here that because what we get is a DOM node (array-like object), we must process it before operation:

object

let p_child=[...parent.children];

array

Then

console.log(child in p_child);

not

! ! !

Why? (At this time, the author has not yet realized the seriousness of the matter)

I wonder if something went wrong, so I use the es6 includes API to verify:

console.log(p_child.includes(child));

yes

That’s right!

Let’s verify it with a normal array:

Verification

? ? ?

At this point, I remembered to check MDN:

mdn

Then I found that: when the in operator is used alone, it detects whether the value corresponding to the value on the left (as an index) is inside the object on the right (on the properties & prototype) !

Back to the code above, we find that:

vertification_2

This verifies our conclusion.

Obviously, "child element" is not equivalent to "existing on the prototype chain" - this leads to another knowledge point: the difference between attribute and property!

So after some "trouble", the source code should be written directly like this:

<div id="root">
    <div class="child">I am a child element</div>
    <button>Remove</button>
</div>
<script>
    let btn = document.querySelector('button')
    let child = document.querySelector('.child')
    let root = document.querySelector('#root')
    let r_child = [...root.children]
    
    btn.addEventListener('click', function() {
        if(r_child.includes(child)){ // Or you can just check if child is null... root.removeChild(child)
        }
    })

</script>

A somewhat hasty ending

Therefore, reading and studying sometimes cannot be "not seeking to understand thoroughly"~

You also need to be brave enough to "trouble around" and learn how to "check documents" [/funny face].

Summarize

This is the end of this article about the JS operator in problem. For more information about the JS operator in problem, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Discussion on the use of typeof and instanceof operators in javascript

<<:  Detailed steps to configure MySQL remote connection under Alibaba Cloud

>>:  Security configuration and detection of SSL after the website enables https

Recommend

How to clear floating example code in css

Overview The framework diagram of this article is...

Implementation of waterfall layout in uni-app project

GitHub address, you can star it if you like it Pl...

Summary of the use of html meta tags (recommended)

Meta tag function The META tag is a key tag in th...

Linux uses lsof command to check file opening status

Preface We all know that in Linux, "everythi...

JavaScript canvas realizes colorful sun halo effect

This article example shares the specific code of ...

Play and save WeChat public account recording files (convert amr files to mp3)

Table of contents Audio transcoding tools princip...

Detailed explanation of the solution for migrating antd+react projects to vite

Antd+react+webpack is often the standard combinat...

Use of Linux ln command

1. Command Introduction The ln command is used to...

How to use vue3 to build a material library

Table of contents Why do we need a material libra...

2 methods and precautions for adding scripts in HTML

How to add <script> script in HTML: 1. You c...

Use of MySQL official export tool mysqlpump

Table of contents Introduction Instructions Actua...

Full analysis of web page elements

Relative Length Units em Description: Relative len...

Detailed explanation of the transition attribute of simple CSS animation

1. Understanding of transition attributes 1. The ...