JavaScript函数IIFE使用详解
一、认识函数
javaScritp中的的函数
//函数声明语法定义
functionfun1(name,age){
console.log(name+','+age);
}
fun1('Amy',18);//Amy,18
//函数表达式定义
varfun2=function(name,age){
console.log(name+','+age);
}
fun1('Amy',18);//Amy,18
javaScript函数带默认参数
/*默认参数*/
functionfun1(name,age=17){
console.log(name+','+age);
}
fun1('Amy',18);//Amy,18
fun1('Amy','');//Amy,
fun1('Amy');//Amy,17
fun1("Amy",null);//Amy,null
函数参数默认值存在暂时性死区,在函数参数默认值表达式中,还未初始化赋值的参数值无法作为其他参数的默认值。
functionfun2(x,y=x){
console.log(x,y);
}
fun2(1);//11
functionfun3(x=y){
console.log(x);
}
fun3();//ReferenceError:yisnotdefined
javaScript函数不定参数
//不定参数用来表示不确定参数个数
functionfun4(...values){
console.log(values.length);
}
fun4(1,2);//2
fun4(1,2,3,4);//4
Function的构造定义
通过Function构造函数创建函数,可向构造函数中传入任意数量的参数,但值得注意的是传入的最后一个参数会作为函数体,而其他参数则作为参数传入函数中。用该方法去定义函数是不推荐使用的,因为该语法会导致解析两次代码,第一次解析常规ECMAScript代码,第二次解析传入构造函数的字符串,影响性能。
varfunctionName=newFunction("value",...,"函数体");
varf2=newFunction("n1","n2","returnn1+n2;");
console.log(f2(1,2));//3
注:函数是引入值类型,所以函数名仅仅是指向函数的指针,当使用函数名去赋值给另一个变量名时,仅仅复制的是一个指针。即在下列a设置为null时,仅将a存的指针消除而已,不会影响b调用函数。
vara=b=function(value1){
returnvalue1;
}
a=null;
b(1);
function中的默认对象叫arguments,类似数组,但不是数组,该对象是传递给函数的参数。我们可以通过这个arguments知道该函数有多少个参数
functioncounter(){
varsum=0;
for(vari=0;i
注:这里的arguments是一个隐式对象,不声明也在函数中,内部函数可以访问外部函数的任意内容,但是不能直接访问外部函数的arguments与this对象。
functionf1(){
console.log(arguments.length);
f2=function(){
console.log(arguments.length);
}
returnf2;
}
varf=f1(1,2,3);//3
f();//0
function.call-调用一个对象的一个方法,以另一个对象替换当前对象
/*构造函数*/
functionStudent(name,age){
this.name=name;
this.age=age;
}
show=function(add){
console.log(add+":"+this.name+","+this.age);
}
//通过new关键字调用构造函数,创建一个对象tom
varrose=newStudent("rose",18);
varjack=newStudent("jack",20);
//调用show方法,指定上下文,指定调用对象,this指向rose,“大家好是参数”
show.call(rose,"大家好");//大家好:rose,18
show.call(jack,"Hello");//Hello:jack,20
call方法中的参数都可以省去,第1个参数表示在哪个对象上调用该方法,或this指向谁,如果不指定则会指向window对象。
varname="无名";
varage=18;//全局变量
show.call();//undefined:无名,18
立即执行表达式函数(IIFE)
块级作用域与函数作用域
functioncalc(){
for(vari=0;i<5;i++){
console.log(i);////0,1,2,3,4
}
console.log(i);//5
}
calc();
函数没有块级作用域所以后面输出的i是5,没有报错
解决方法,模拟一个块级作用域
functioncalc(){
//IIFE
(function(){
for(vari=0;i<5;i++){
console.log(i);//0,1,2,3,4
}
})();
console.log(i);//报错
}
calc();
函数表达式或匿名对象立即执行
//调用匿名函数
(function(){
console.log("这是一个函数表达式");
})();
//调用匿名对象
({
name:"foo",
show:function(){
console.log(this.name);
}
}).show();
console.log({a:1}.a);
console.log({a:function(){}}.a());
多种函数立即表达式的写法
//最常用的两种写法
(function(){/*code*/}());//推荐写法
(function(){/*code*/})();//当然这种也可以
//括号和JS的一些操作符(如=&&||,等)可以在函数表达式和函数声明上消除歧义
//如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
//但是两者交换则会报错
vari=function(){return10;}();
true&&function(){/*code*/}();
0,function(){/*code*/}();
//如果你不怕代码晦涩难读,也可以选择一元运算符
!function(){/*code*/}();
~function(){/*code*/}();
-function(){/*code*/}();
+function(){/*code*/}();
//你也可以这样
newfunction(){/*code*/}
newfunction(){/*code*/}()//带参
立即表达函数带参数
(function(n){
console.log(n);//100
})(100);
最好在立即表达函数前面添加分号
vark=100
(function(n){
console.log(n);
})(k);
//出错,解释器会认为100是函数
vark=100
;(function(n){
console.log(n);
})(k);
IIFE的形变
(function(n){
console.log(n);
//认为这里有30000代码
}(100));
如果中间有很长的代码,参数100只有到文档的末尾才可以看得到,变形后的结果:
(function(exp){
exp(100);
}(function(n){
console.log(n);
//认为这里有30000代码
}));
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。