认识setTimeout

面试题:

写一个 setInterval(fn, a, b),每次间隔 a,a+b,a+2b,....,a+nb调用fn,然后写一个 clear函数,清除setInterval函数。

思路:使用setTimeout函数计时,重复调用可以考虑使用循环语句,或者我们也可以使用递归调用,那就需要添加条件判断了,不然会导致栈溢出,但是由于此处是setTimeout函数,调用递归函数会有时间延迟,所以不会导致立即导致栈溢出,因此我们可以不用写条件判断,setInterval函数就写完了,剩下的就是写clear函数了。

function setInterval(fn, a, b) {
    let n = 0
    let timer
    function loop() {
     timer = setTimeout(function() {
        fn()
        n++
        loop()
      }, a + n*b)
    }
   loop()
  return timer
}
let time = setInterval(()=>{console.log('tes')}, 1000, 2000)

上面的代码完成了间隔调用函数fn的功能,没有完成clear函数的功能

完整的解决方法可以参考此链接

 

setTimeout函数的实际应用:

案例引自MDN:给不支持setTimeout添加第三个参数的IE9打补丁。

setTimeout(function(arg1) {
    if (arg1 === 'test') {
      // 检测原生的setTimeout是否支持传入第三个参数
      return;
    }
  // __natuveST__ 指原生的setTimeout
    var __nativeST__ = window.setTimeout;
    window.setTimeout = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) {
    // 从arguments第三个参数开始拷贝并赋值给aArgs
      var aArgs = Array.prototype.slice.call(arguments, 2);
    // 检测vCallback是否是函数
      return __nativeST__(vCallback instanceof Function ? function() {
        vCallback.apply(null, aArgs);
      } : vCallback, nDelay);
    };
  }, 0, 'test');

 

如何解决setTimeout的this指向问题:(默认情况下回调函数的this指向全局对象)

1.可以在回调函数外层包裹一个匿名函数,来创建新的执行环境

function test() {
  return console.log(this)
}
const o = {}
o.test = test
// 我们希望返回的是o这个对象
setTimeout(o.test, 2000) // window

修改后的代码:

function test() {
  return console.log(this)
}
const o = {}
o.test = test
setTimeout(()=>{o.test()}, 2000) //  {test: f}

 

2. 修改原生setTimeout函数的this指向

let newSetTimeout = window.setTimeout
window.setTimeout = function (callback, delay) {
  let args = Array.prototype.slice.call(arguments, 2),
      _this = this
  return newSetTimeout(
      callback instanceof Function ? function(){callback.apply(_this, args)} : callback, delay) 
}

3.在回调函数上使用bind函数修改this指向

function test() {
  return console.log(this)
}
const o = {}
o.test = test
setTimeout(o.test.bind(o), 2000) // {test: f}

 

 

 

 

posted @ 2020-12-01 14:39  xqcokid  阅读(76)  评论(0编辑  收藏  举报