JS 函数的执行时机

183 阅读2分钟

定义函数有4种方式

1.使用function关键字声明函数,并指定函数名

function 函数名(形式参数){
    语句
    return  返回值
}

这种函数称为具名函数,具备“函数提升”,即无论在哪里声明具名函数,它都会跑到第一行。

2.函数表达式

let 变量 = function (形式参数){
    语句
    return 返回值
}

同样使用function关键声明一个函数但未指定函数名,这样的函数称为匿名函数。一般将匿名函数赋值给一个变量,=右边称为函数表达式。

需要注意的是,函数表达式不具备函数提升,并要注意作用域范围

3.箭头函数

let f1 = x => x*x
let f2 = (x,y) => x+y   //括号不能省
let f3 = (x,y) => {     //花括号不能省
    console.log('haha')
    return x+y
}
let f4 = (x,y) => ({name:x ,age:y}) //直接返回一个对象时,需要加圆括号

4.构造函数

let f = new Function('x','y','return x+y')

通过使用构造函数定义一个函数可以知道,所有函数都是由Function构造出来的,包括Object、Array、Function自己。

常见问题:为什么以下代码会打印6个6

let i = 0
for(i=0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

setTimeout表示过一段时间再执行某个函数或代码,因此上面for循环会先执行完成,得到i=6,然后setTimeout再执行。for一共循环了6次,setTimeout也被挂起6次,所有最后打印出6个6。

如何打印出0~5?

letfor一起使用可产生神奇效果。

for(let i=0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
} //得到0,1,2,3,4,5

其他打印出0~5的方法

函数执行时机不同,结果不同。之前之所以打出6个6是因为for循环执行完成后setTimeout才执行。为了打出0~5,每次循环时要把i存下来给setTimeout执行时候使用,通过查找网道JS教程,setTimeout除了前两个参数,还允许更多参数,它们将依次传入推迟执行的函数。因此将i作为第3个参数传入函数。

let i = 0
for(i=0; i<6; i++){
  setTimeout((j)=>{
    console.log(j)
  },0,i)
}  //依次打出0~5