JavaScript基础5:定时器以及定时器存在的问题

1 两种定时器

1.1 延迟定时器

setTimeout(code, time, par…)

  1. code: 延迟一段时间之后,做需要做的事,
    可以是个function(时间到了自动调用),string(不推荐)
  2. time:延迟的事件
  3. parma1…parmaN:定时器完成需要执行code时,作为参数传入code中
    IE9及其以下存在兼容问题
    document.onclick = function () {
        setTimeout(
            function (a, b, c) {
                console.log(a + b + c);
            }, 1000, 1, 2, 3
        );
    }

1.2 间隔定时器

setInterval(code, time, par…) 结束之前反复执行

2 清除定时器

2.1 清除延时定时器

每个定时器都会有一个返回值,这个返回值就是定时器的id

  1. 这个id是唯一数字
  2. 是一个正整数

clearTimeout(id) :id是要清除的定时器编号

在这里插入图片描述

2.2 定时器的问题

频繁去开启一个定时器的话,定时器会启动多个,然后如果去记录一个定时器返回的id 的话就会造成后面的定时器覆盖前面的定时器id的情况
在这里插入图片描述

清除间隔定时器的方法:管理定时器

  1. 每次开启定时器的时候先清除上一次的定时器

     var t1;
        var t2;
        var t3;
        var btns = document.querySelectorAll('button');
        btns[0].onclick = function () {
            clearTimeout(t1);
            clearTimeout(t2);
            clearTimeout(t3);
            t1 = setTimeout(
                function (a, b, c) {
                    console.log('定时器1');
                }, 1000
            );
            t2 = setTimeout(
                function (a, b, c) {
                    console.log('定时器2');
                }, 2000
            );
            t3 = setTimeout(
                function (a, b, c) {
                    console.log('定时器3');
                }, 3000
            );
            console.log(t1, t2, t3);
        }
    
        btns[1].onclick = function () {
            clearTimeout(t3);
        }
    

    这样虽然定时器返回的id会改变,但是因为已经清了上次的定时器,所以事件只会执行一次

  2. 开关,在上一次的定时器未关闭的情况下不允许开启下一次定时器

        btns[0].onclick = function () {
            if (onOff) {
                t1 = setTimeout(
                    function (a, b, c) {
                        console.log('定时器1');
    
                    }, 1000
                );
            }
            onOff = false;
        }
    
        btns[1].onclick = function () {
            clearTimeout(t1);
            onOff = true;
        }
    

3定时器注意事项

3.1 定时器里的this指向

this是谁调用,就指向谁
但是定时器是js本身就定义好的函数,被定义在window下面
所以是通过window进行调用的
所以定时器里的this就指向window
在这里插入图片描述
在这里插入图片描述

定时器this指向的解决方法

定义一个_this变量存储事件函数中的this指向
在这里插入图片描述

3.2 不推荐第一个参数(code)使用字符串

  1. 影响性能
    1. 首先解析字符串
    2. 解析函数然后执行
      有两次解析的过程
  2. web安全 xss注入
    可以通过输入字符串的方式调用函数
    在这里插入图片描述
    但是如果输入一个无限循环的函数,就会进入死循环,这就是xss注入
    在这里插入图片描述

解决方法

后端和前端共同解决

3.3 第二个参数time最小执行时间

  • 默认为0,但是执行代码任有延迟(>= 4ms)

  • 经典面试题

        for (var i = 0; i < 5; i++) {
            setTimeout(function () {
                console.log(i);
            });
        }
    

    for循环执行非常快,导致setTimeout获取的i是for循环结束之后的i

3.4 传参问题

  • IE9以下不支持定时器传参
  • 给定时器内的有名函数传参会使函数立即执行(因为加了括号)

解决方法

  1. 字符串,但是会被解析两次并且有xss注入的安全问题(不推荐)

    setTimeout('fn(参数)', 1000);
    
  2. 用匿名函数包一下

    setTimeout(function() {
    	fn(par);
    	}, 1000);
    
  3. bind
    先复习一下传值传址的问题
    在这里插入图片描述
    getNewAge === window.getNewAge,指向的是window
    解决方法就是使用bind()
    在这里插入图片描述
    改变了this的指向变为obj
    同理bind就可以进行参数传递

        var obj = {
            age: 18,
            getAge: function(a, b, c) {
                console.log(a, b, c);
            }
        }
    
        var getNewAge = obj.getAge.bind(obj, 1, 2, 3);
        getNewAge();
    

    用于定时器

        setTimeout(fn.bind(null, 2), 1000);
        // 改变this指向window可以写成null
        function fn(n) {
            console.log(n);
        }
    
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值