Writing in the front

Recently, I saw some front-end information, and also started to write some code, record and summarize some of the more weird JS usage encountered in the process of practice, hoping to help you, but also to improve their own.

The text start

1. Obtain the node

So let’s look at a piece of code and think about what’s going to happen?


<body>
    <p>The title</p>
</body>

<script type="text/javascript" language="javascript">
    var pNodes = document.getElementsByTagName("p")
    for (let i=0; i< pNodes.length; i++)  {
        pNode = pNodes[i]
        // This is just to show that the corresponding logic actually needs additional style additions for the new nodes
        const newPNode = document.createElement("p");
        // The new node is added after the old node
        pNode.parentNode.appendChild(newPNode)
    }
</script>

Copy the code

Unfortunately, this code will cause the browser to freeze and the loop won’t end. Here’s why and how to avoid it.

    1. JavaScript document.getElementsByTagName("p")Returns an array object of nodes;
    1. JQuery $("td")JQuery’s element selector is also an array object of returned nodes;

It is important to note the document. The getElementsByTagName (” p “) returns the DOM structure of the dynamic, change the DOM, the result will change; $(” TD “) returns static results of jquery selector method execution.

Therefore, when manipulating such array nodes dynamically, it is important to note whether the array object returned by the selector is mutable or immutable.

2. Sibling nodes

What is the result of the following code?

 <body>
    <ul >
        <li id='1'>1</li>
        <li id='2'>2</li>
        <li id='3'>3</li>
    </ul>
    <script>
        l1 = document.getElementById("1")
        console.log(l1.nextSibling) 
        // #text
    </script>
 </body>
Copy the code

  • 2
  • The solution is to use nextElementSibling

     <body>
        <ul >
            <li id='1'>1</li>
            <li id='2'>2</li>
            <li id='3'>3</li>
        </ul>
        <script>
            l1 = document.getElementById("1")
            console.log(l1.nextElementSibling)
        </script>
     </body>
    Copy the code

    Conclusion:

    • The nextSibling attribute returns siblings (including text nodes, comment nodes) after the element node;
    • The nextElementSibling attribute returns only the sibling nodes following the element node (excluding text nodes, comment nodes);

    3. Variable promotion mechanism

    What does the following code output?

    function getValue(flag) {
        console.log(value) // undefined
        if (flag) {
            var value = "hello world";
            return value
        } else {
            console.log(value) // undefined
            return null;
        }
    }
    getValue()
    Copy the code

    The answer is not quite what you think it is because of the mechanism of variable promotion, so if you declare a variable with the keyword var it will be declared first in the pre-compilation phase, something like that

    function getValue(flag) {
        var value;
        if (flag) {
            var value= "hello world";
            return value;
        } else {
            return null; }}Copy the code

    4. Internal variables of the function

    What does the following code output?

    var name = "hello";
    function setName(){
        name = "world";
    }
    setName();
    console.log(name); 
    // world
    Copy the code
    var name = "hello";
    function setName(name){
        name = "world";
        console.log(name) // world
    }
    setName();
    console.log(name); // hello
    Copy the code

    Summary: Internal variables take precedence over global variables for internal functions, but global variables are used for undeclared local variables (parameters are also local variables); When using var to define variables, be careful to use scope. It is best to use ES const let instead to reduce unnecessary system problems.