当前位置: 首页 > 科技观察

JavaScript中你不知道的函数

时间:2023-03-11 23:35:45 科技观察

函数声明在JavaScript中,函数声明有两种表达形式,声明式和表达式式,至于其他函数(如立即执行函数、箭头函数等)都是基于这两个派生自一个表格。//declarativefunctionfoo(){console.log('Iamadeclarative')}//expressionvarfoo=function(){console.log('Iamanexpression')}命名函数,命名函数是一个带有一个名字。这是我们最常用的功能。我们来看看它是怎么写的。//命名函数functionfoo(){console.log('我是一个命名函数')}上面说了函数声明有两种表达方式。命名函数是经典的声明,命名函数的另一种表达形式引入了另一种类型的函数——命名函数表达式(NFE)。命名函数表达式命名函数表达式是命名函数的表达式。严格来说,它不是函数类型,而是一种写法。//命名函数表达式varfn=functionfoo(){console.log('我是一个命名函数表达式');}fn()//输出:我是一个命名函数表达式它有几个特点:函数名标识符函数私有化nameidentifierconstant函数名标识符私有化:即命名函数表达式的函数名不能被外部调用,只在函数体内使用,外部调用会报错。//函数名私有化varfn=functionfoo(){console.log(typeoffoo);}fn()//functionfoo()//UncaughtReferenceError:fooisnotdefinedfunctionnameidentifierconstantization:命名函数表达式标识符的值不能修改,我们可以将其用作常量。varfn=functionfoo(){foo=12;console.log(foo);}fn()/*Output:?foo(){foo=12;console.log(foo);}*/来看一个经典的面试题//改写下面的代码,让它分别输出10和12varfoo=10;(functionfoo(){foo=12;console.log(foo);})()//改写结果varfoo=10;(functionfoo(){varfoo=12;console.log(window.foo);//10console.log(foo);//12})()匿名函数匿名函数:即没有名字的函数,匿名函数不能像命名函数一样直接声明和定义,在JavaScript中一个常见的用法是使用匿名函数作为回调参数或者作为高阶函数的返回值。//作为回调参数setTimeout(function(){console.log('我是匿名函数');},1000);//作为高阶函数的返回值functionfoo(){varnum=10;returnfunction(i){returnnum+i;}}foo()(5)//Output:15匿名函数有几个缺点我们需要注意:没有函数名,调试困难如果需要引用自身(比如作为递归函数),需要使用arguments.callee,但是arguments.callee在严格模式下禁用了较差的可读性ImmediatelyExecutingFunctionsImmediatelyExecutingFunctions(IIFE):即当程序解析到函数时,立即执行。//写一个(function(){console.log('我是一个立即执行函数');})()//写两个(function(){console.log('我是一个立即执行函数');}())匿名函数的好处是内部参数不会泄露,即变量私有化。(function(){varx=10console.log('我正在立即执行函数');}())console.log(x);//UncaughtReferenceError:xisnotdefined有个很经典的面试题,大家可以看看.//重写下面的代码,让它顺序输出。for(vari=0;i<5;i++){setTimeout(function(){console.log(`valueis${i}`)},0)}//此时会输出“value5”5次。我们马上就会想到使用let,但是有没有其他的写法呢?当然,直接执行函数即可。//重写方法一for(vari=0;i<5;i++){(function(num){console.log(`valueis${num}`)})(i)}//重写方法二for(vari=0;i<5;i++){varnum=(function(){returni;})()console.log(`valueis${num}`)}