一、函数、函数表达式、回调函数
1、函数:
function say(){
console.log("哈哈哈哈哈哈!")
}
注:Javascript引擎在解析javascript代码时会‘函数声明提升’(Function declaration Hoisting)。也就是说我函数可以先调用后声明,但是js引擎在执行js代码时会自动先去寻找代码中的函数先执行。
2、函数表达式:
1、function (){
console.log("hello world")
}
2、var say = function(){
console.log(23)
}
3、(function(num) {
console.log(num)
}(23))
//输出:23
4、(function(a,b,c) {
console.log(a,b,c)
})(1,2,3)
//输出:1,2,3
(1)匿名函数也属于函数表达式。
(2)函数表达式不会向函数那样有函数“声明提升”,如果你先使用“函数表达式”再去声明“函数表达式”则系统会报错。
(3)在函数后面加括号如3、4,在js中有特殊的含义,代表立即执行函数。全称Immediately-Invoked Function Express:立即执行函数表达式。比如(function(){})()//匿名函数自调用
3、回调函数
function title(value){//这是回调函数!!!!
alert(value);
}
function main(title, value){//这个主函数:在参数列表中,title作为一个参数传递进来,也就是上文说的 参数化函数;然后value这个值正是title()函数中所需要的。
alert("我是主函数");
title(value);//结果为:'我是回调函数'。——————然后在这行这个title(),它就是回调函数咯。
}
main(title,"我是回调函数");//title参数加上()后,就会变回一个函数,并会被执行一次。
二、一道有关执行顺序的面试题
题目描述:请写出下面代码的打印输出:
setTimeout(function(){
console.log(1)
},0)
for(let i=10;i<30;i+=10){
setTimeout((function(i){
console.log(i)
return ()=>i
})(i),i*100)
}
new Promise(function(resolve){
console.log(2)
for(var i=0;i<100000000;i++){
if(i==99999999){
console.log(resolve())
}
}
console.log(4)
}).then(function(){
console.log(3)
return 3.1
})
console.log(5)
答案:10 、20、2、undefined、4、5、3、1
解析:
(1)顺序执行第一个setTimeout,由于是定时器函数故console.log(1)进入宏队列等待执行。// 输出:[ ], 宏队列:[1], 微队列:[ ]。
(2)进入for循环,执行setTimeout,注意这里虽然是定时器的回调函数,但是他是用的(function(){})()这种形式的函数表达式,故这里的function函数立即执行。第一次循环输出10,第二次循环输出20 。// 输出:[10,20],宏队列:[1],微队列:[ ]。
(3)执行promise函数,同步执行function(resolve){}函数(不清楚为什么立即执行的可以看我的上一篇文章),打印2,进入for循环,打印resolve()也就是undefined,for循环执行完毕后打印4。与promise同步执行then,但是then中的回调函数有返回值后开始执行并进入微队列等待。 // 输出:[10,20,2,undefined,4],宏队列:[1],微队列:[ 3]。
(4)promise同步执行的都执行完毕后,执行console.log(5) 。 //输出:[10,20,2,undefined,4,5],宏队列:[1],微队列:[ 3]
(5)同步执行的代码全部执行完毕,先执行微队列,再执行宏队列。 //输出:[10,20,2,undefined,4,5,3,1]