setTimeout

参考
1. MDN window.setTimeout
2. JavaScript 标准参考教程 - 定时器
3. 你所不了解的setTimeout
4. 彻底理解setTimeout()

API语法
var timerId = setTimeout(func | code[, delay]);
var timerId = setTimeout(func[, delay, param1, param2])
  • API中第一个参数是function或者字符串形式的code,正常情况下使用function
  • Node中第一个参数非function会报错;
  • IE10+才支持带param写法;
  • delay可省略,默认为0;
  • this指向默认为window
  • code形式是没有第三个参数的,即使写了也读取不到arguments
1. 写法对比
// 浏览器
var func = function() {
  console.log(1)
}

// 正常写法,延迟输出1;
setTimeout(func, 1000)

// 此处func()立即执行,返回undefined,相当于
// func()
// setTimeout(undefined, 1000)
// 立即输出1
setTimeout(func(), 1000)

// 字符串写法,同正常写法,延迟输出1
setTimeout('func()', 1000)
2. 异步输出

delay为0依然是异步输出

console.log(1)
setTimeout(function () {
  console.log(2)
}, 0)
console.log(3)
// 1 3 2
3. 见怪不怪的一题
for (var i = 1; i < 5; i++) {
  setTimeout(function () {
    console.log(i)
  }, i * 1000)
}
// 5 5 5 5
  1. for循环中var声明的是全局作用域
  2. setTimeoutfunction现在一边观望
  3. 同步操作完成后,functioni随着作用域链找到全局中的i

使结果预期为1 2 3 4的方法之一就是创建一个作用域用来覆盖全局作用域中的i变量

for (var i = 1; i < 5; i++) {
  (function (i) {
    setTimeout(function () {
      console.log(i)
    }, i * 1000)
  })(i)
}
// 1 2 3 4

方法之二是利用API中的第三个参数,传参进去

for (var i = 1; i < 5; i++) {
  setTimeout(function (i) {
    console.log(i)
  }, i * 1000, i)
}
// 1 2 3 4

此时function中的i其实与全局的i没什么关系了,相当于:

for (var i = 1; i < 5; i++) {
  setTimeout(function (j) {
    console.log(j)
  }, i * 1000, i)
}
// 1 2 3 4

方法之三是ES6中let声明的块级作用域

for (let i = 1; i < 5; i++) {
  setTimeout(function () {
    console.log(i)
  }, i * 1000)
}
// 1 2 3 4

那以下代码输出什么呢?

var i = 100;
for (let i = 1; i < 5; i++) {
  setTimeout(function (i) {
    console.log(i)
  }, i * 1000)
}
// undefined undefined undefined undefined

出这题应该很变态了,但想到第一个参数总是一个不能传参的函数,假设是temp,执行时相当于temp(),并没有任何参数传入,所以预期的i始终为undefined。感觉可以将每个setTimeout函数都可以如下

var i = 100;
for (let i = 1; i < 5; i++) {
  var temp = function (i){
    console.log(i)
  }
  setTimeout(temp, i * 1000)
}
// undefined undefined undefined undefined

方法之四是使用bind传入参数

for (var i = 1; i < 5; i++) {
  setTimeout(function (i) {
    console.log(i)
  }.bind(null, i), i * 1000)
}
// 1 2 3 4
4. Todo
  1. 传参
  2. debounce--见参考2

转载于:https://www.cnblogs.com/guidetheorient/p/8556000.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值