函数是一种对象,函数是由 Function 构造的
Function.__proto__ === Function.prototype
// >>true
函数的要素
每个函数都有默认的调用时机
let a = 1
function fn(){
console.log(a)
}
a = 2
fn()
// >>2
函数的调用时机 && setTimeout()
let a = 1
function fn() {
setTimeout(()=>{
console.log(a)
}, 0)
}
fn()
a = 2
// >> a = 2
这里的 setTimeout 方法是一个定时器,在定时器到期后即执行代码,定时为默认值 0 时,意味着:“马上”执行代码,实际的延迟时间可能会比期待的(delay 毫秒数)更长。
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
}, 0)
}
// >> 6, 6, 6, 6, 6, 6
为什么会打印出 6 个 6 ?
同上,因为setTimeout
是异步执行,在delay
值取为 0 时,“马上”执行代码,所以它会在for
循环结束后执行。
此时的变量i
,值已经被覆盖成6
了,所以会执行6
次console.log(6)
那如何才能得到符合我们直觉的0 - 5
在for
循环中使用let
声明变量
for(let i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
// >> 0, 1, 2, 3, 4, 5
因为在let
中,let
有自己的作用域块,所以在for
循环的表达式中使用let
,等价于在代码块中使用let
。
- for (let i = 0; i< 5; i++) || 这句话的圆括号之间,有一个隐藏的作用域
- for (let i = 0; i< 5; i++) { 循环体 } || 在每次执行循环体之前,JS 引擎会把
i
在循环体的上下文中重新声明及初始化一次,即每次循环会多创建一个i
另一种方法得到0 - 5
let i = 0
for(i = 0; i<6; i++){
setTimeout((value)=> {
console.log(value)
},0,i)
}
// >> 0, 1, 2, 3, 4, 5
把i
作为参数传入到setTimeout()
中即可实现打印出0 - 5
了