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 implement CSS mask full screen center alignment

The specific code is as follows: <style> #t...

Nginx Location Configuration Tutorial from Scratch

Basics The matching order of location is "ma...

How to use VirtualBox to build a local virtual machine environment on Mac

1. Big Data and Hadoop To study and learn about b...

Detailed explanation of the use of Element el-button button component

1. Background Buttons are very commonly used, and...

After reading the introduction of CSS box model, you will not be confused

The property names often heard in web design: con...

Detailed explanation of the background-position percentage principle

When I was helping someone adjust the code today,...

Solve the group by query problem after upgrading Mysql to 5.7

Find the problem After upgrading MySQL to MySQL 5...

DIV common attributes collection

1. Property List Copy code The code is as follows:...

JavaScript super detailed implementation of web page carousel

Table of contents Creating HTML Pages Implement t...

Description of the hr tag in various browsers

Generally, we rarely meet HR, but once we do, it c...

Simple Implementation of HTML to Create Personal Resume

Resume Code: XML/HTML CodeCopy content to clipboa...

MySQL 5.7.27 installation and configuration method graphic tutorial

The installation tutorial of MySQL 5.7.27 is reco...

Detailed explanation of Linux command unzip

Table of contents 1. unzip command 1.1 Syntax 1.2...