setTimeout引发的刨根问底

setTimeout定时器)是JavaScript中一个比较重要且常用的方法,该方法用于在指定的毫秒数后调用函数或计算表达式。平时开发可能基本都是使用 setTimeout(fn, ms) 的形式,当然还有比较神奇的用法,特别是在前端面试中,经常被问到。

JavaScript setTimeout

一、setTimeout 介绍

  1. 定义: setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。

  2. 语法

setTimeout(code, milliseconds, param1, param2, ...)
setTimeout(function, milliseconds, param1, param2, ...)
参数描述
code/function必需。要调用一个代码串,也可以是一个函数。
milliseconds可选。执行或调用 code/function 需要等待的时间,以毫秒计。默认为 0。
param1, param2, …可选。 传给执行函数的其他参数(IE9 及其更早版本不支持该参数)。

二、使用

  1. 第一个参数为 code 字符串形式:
setTimeout("console.log('Hello setTimeout')", 2000)
  1. 第一个参数为 function 函数形式(推荐):
setTimeout(function(){
  console.log('Hello setTimeout')
}, 2000)
  1. 传参:
setTimeout(function(params){
  console.log(`参数:${params}`)
  console.log('Hello setTimeout')
}, 2000, 'setTimeout params')

/* 打印输出 */

// 参数:setTimeout params
// Hello setTimeout

三、经典面试题

  1. 基础
for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000 * i);
}

输出: 开始输出一个 5,然后每隔一秒再输出一个 5,一共 5 个 5。
解析: var声明的 i 变量提升

  1. 优化:输出 0 到 4,且每个间隔一秒
for (var i = 0; i < 5; i++) {
  (function(i) {
    setTimeout(function() {
      console.log(i);
    }, i * 1000);
  })(i);
}

解析: 自执行函数形成闭包,而 JS 函数中基本类型的参数传递是按值传递
更加直观的形式:

function output(i) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}

for (var i = 0; i < 5; i++) {
  output(i);
}
  1. 其他方法:
  • 利用 ES6 中的 let 声明的变量形成块级作用域
for (let i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000 * i);
}
  • 利用 setTimeout 中第三个参数,保持参数的引用。
for (var i = 0; i < 5; i++) {
  setTimeout(function(i) {
    console.log(i);
  }, 1000 * i, i);
}

四、举一反三

  1. 删除自执行函数的参数
for (var i = 0; i < 5; i++) {
  (function() {
    setTimeout(function() {
      console.log(i);
    }, i * 1000);
  })(i);
}

输出: 开始输出一个 5,然后每隔一秒再输出一个 5,一共 5 个 5。

  1. 变形
for (var i = 0; i < 5; i++) {
  setTimeout((function(i) {
    console.log(i);
  })(i), i * 1000);
}

直接看不太容易理解,拆解一下:

for (var i = 0; i < 5; i++) {
  var fn = (function(i) {
    console.log(i);
  })(i);
  setTimeout(fn, i * 1000);
  
  // 相当于下边的
  // setTimeout(undefined, i * 1000)
}

输出: 直接输出 0 到 4,中间没有间隔。
解析: fn 接收的是一个没有返回值的自执行函数,所以这里的 fn 为 undefined,相当于执行了 setTimeout(undefined, i * 1000) 无效,也不会报错。


欢迎访问:天问博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值