setTimeout和setInterval的使用的时候的问题总结

this的指向问题

由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象
例子(来自MDN)

let myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
     
    alert(arguments.length > 0 ? this[sProperty] : this);
};

myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"

使用定时器

setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
// 对定时器其设置call也是没有
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error

解决方法

// 一个通用的方法是用包装函数来设置this
// zqx:function(){myArray.myMethod()}这个函数中的this依旧是window;但是myArray.myMethod()中的this依旧是myArray
setTimeout(function(){
     myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
setTimeout(function(){
     myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds
// 将执行函数用bing绑定
// zqx:这里和上面对定时器绑定call是同的哦
let myArray = ['zero', 'one', 'two'];
myBoundMethod = (function (sProperty) {
     
    console.log(arguments.length > 0 ? this[sProperty] : this);
}).bind(myArray); 

myBoundMethod(); // prints "zero,one,two" because 'this' is bound to myArray in the function
myBoundMethod(1); // prints "one"
setTimeout(myBoundMethod, 1000); // still prints "zero,one,two" after 1 second because of the binding
setTimeout(myBoundMethod, 1500, "1"); // prints "one" after 1.5 seconds

执行队列问题

setTimeout并不一定是在到了指定时间的时候就把事件推到任务队列中,只有当在任务队列中的上一个setTimeout事件被主线程执行后,才会继续再次在到了指定时间的时候把事件推到任务队列,那么setTimeout的事件执行肯定比指定的时间要久,具体相差多少跟代码执行时间有关

setInterval则是每次都精确的隔一段时间就向任务队列推入一个事件,无论上一个setInterval事件是否已经执行,所以有可能存在setInterval的事件任务累积,导致setInterval的代码重复连续执行多次,影响页面性能。

setTimeout(
() => {
     
  console.log('1')
  let arr = []
  for(let i = 0; i < 100000000; i++) {
     
    arr[i] = i
  }
},
1000)
setTimeout(() => {
     
  console.log('3')
},1000)
 
// 输出1 3 是由时间间隔的 因为处理第一个定时器是要时间的

最小延时和最大延时

最小:在浏览器中,setTimeout()/setInterval() 的每调用一次定时器的最小间隔是4ms

最大:包括 IE, Chrome, Safari, Firefox 在内的浏览器其内部以32位带符号整数存储延时。这就会导致如果一个延时(delay)大于 2147483647 毫秒 (大约24.8 天)时就会溢出,导致定时器将会被立即执行。

你可能感兴趣的:(javascript,定时器,js,setTimout,setInterval)