Dom(九)——this & 闭包

174 阅读2分钟

this指针问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <!-- 
    this指向 (给谁绑定的事件/方法 谁就是this)
    1. 事件处理函数中  this -> 绑定事件的DOM元素
    2. 在自定义函数中 this -> window
    3. 定时器中 this -> window
    4. 在自定义对象中 this -> 对象
    5. 在类中 this -> 实例化的对象
   -->
    <script>

        var ali = document.getElementsByTagName("li");
        for(var i = 0;i < ali.length;i++){
            ali[i].onclick = function(){
                setTimeout(function(){
                    console.log(this.innerHTML)
                }.apply(this),3000)
                //这里使用apply和call定时器不会有暂停时间,但如果使用bind那么就会正常执行定时器的间隔时间
            }
        }
    // call 改变this指针的方法 参数是多个 第一个参数是要改变的指针 后面的所有的参数都是方法的实参 方法会自动触发
    // apply 改变this指针的方法 参数是2个 第一个参数是要改变的指针 第二个参数是一个数组,数组的每一项就是方法的实参 方法会自动触发
    // bind 改变this指针的方法 参数是多个 第一个参数是要改变的指针 后面的所有的参数都是方法的实参 但是方法不会自动执行
    </script>
    

</body>
</html>

构成闭包的要求

  1. 必须要有两个嵌套关系的函数
  2. 里面的函数会调用外面函数的变量

闭包的优势

  1. 变量会存在内存中,不会被垃圾回收机制回收
  2. 可以通过索引拿到相应变量

闭包的缺点

  • 极有可能造成泄露或者溢出

利用闭包可以解决列表遍历的问题

  • 利用this指针遍历列表
 for(var i = 0;i<ali.length;i++){
            ali[i].index = i;
            ali[i].onclick = function(){
                console.log(ali[this.index])
            }
        }

  • 利用改变指针方法遍历列表
 for(var i = 0;i <ali.length;i++){
            ali[i].onclick = function(){
                setTimeout(function(){
                    console.log(this.innerHTML)
                }.call(this),3000)
            }
        }
  • 利用闭包遍历列表
for(var i = 0;i<ali.length;i++){
            (function(j){
                ali[j].onclick = function(){
                    console.log(j + 1)

                }
            })(i)
            // 函数嵌套函数构成一个闭包
        }

闭包(通俗来讲就是函数里面嵌套函数)

如:

function f1(){
            var x = 1;
           return function(){
                x++;
                console.log(x);
            }
        }
        var s = f1();
        s();
        s();
        s();