函数声明
在JavaScript中,对于函数的声明有两种表达形式, 声明式 和 表达式 ,至于其他函数(如立即执行函数,箭头函数等)都是基于这两种形式衍生的。
//声明式
functionfoo(){
console.log('我是声明式')
}
//表达式
varfoo=function(){
console.log('我是表达式')
}
具名函数
故名思意,具名函数就是有名称的函数,这是我们最常见的一种函数,我们先来看看它的写法。
//具名函数
functionfoo(){
console.log('我是具名函数')
}
上边说了,函数声明的表达形式有两种,具名函数是经典的声明式,具名函数表达式的另外一种表现形式引出了另外一种函数类型- 具名函数表达式(NFE) 。
具名函数表达式
具名函数表达式就是具名函数的表达式写法,严格来说,它并不是一种函数类型,只是一种写法而已。
//具名函数表达式
varfn=functionfoo(){
console.log('我是具名函数表达式');
}
fn()//输出:我是具名函数表达式
它有几个特点:
函数名标识符私有化:即具名函数表达式的函数名不能从外部调用,仅供函数体内部使用,当外部调用时就会报错。
//函数名称私有化
varfn=functionfoo(){
console.log(typeoffoo);
}
fn()//function
foo()//UncaughtReferenceError:fooisnotdefined
函数名标识符常量化:即具名函数表达式标识符的值不能修改,我们可以将其当作常量来使用。
varfn=functionfoo(){
foo=12;
console.log(foo);
}
fn()
/*
输出:
ƒfoo(){
foo=12;
console.log(foo);
}
*/
我们来看一道经典的面试题
//改写以下代码,使其分别输出10、12
varfoo=10;
(functionfoo(){
foo=12;
console.log(foo);
})()
//改写结果
varfoo=10;
(functionfoo(){
varfoo=12;
console.log(window.foo);//10
console.log(foo);//12
})()
匿名函数:即没有名称的函数,匿名函数不能像具名函数一样直接声明定义,在JavaScript中常见的用法就是将匿名函数当作回调参数使用或作为高阶函数的返回值。
//作为回调参数
setTimeout(function(){
console.log('我是匿名函数');
},1000);
//作为高阶函数的返回值
functionfoo(){
varnum=10;
returnfunction(i){
returnnum+i;
}
}
foo()(5)//输出:15
匿名函数有几个缺点我们需要注意一下:
立即执行函数
立即执行函数(IIFE):即当程序解析到该函数时就立即执行。
//写法一
(function(){
console.log('我是立即执行函数');
})()
//写法二
(function(){
console.log('我是立即执行函数');
}())
匿名函数的优点在于内部参数不会泄露,即变量私有化。
(function(){
varx=10
console.log('我是立即执行函数');
}())
console.log(x);//UncaughtReferenceError:xisnotdefined
有一道很经典的面试题,我们可以看一下。
//改写以下代码,让其依次输出.
for(vari=0;i<5;i++){
setTimeout(function(){
console.log(`值为${i}`)
},0)
}
//此时会输出5次"值为5"
我们会立马想到用 let ,但是还有没有其他写法呢?当然有,立即执行函数就是了。
//改写方法一
for(vari=0;i<5;i++){
(function(num){
console.log(`值为${num}`)
})(i)
}
//改写方法二
for(vari=0;i<5;i++){
varnum=(function(){
returni;
})()
console.log(`值为${num}`)
}
原文地址:https://juejin.im/post/6891565170167021576?utm_source=tuicool&utm_medium=referral