作为学前端的小白,刚开始学到函数作为参数传递时,简直一脸的懵逼,为什么有时候要加括号,有时候又不用,特别是遇到setInterval的时候。
下面是参考网上的一些答案,做的一些总结【要是有什么错误不合理的地方,烦请指正哦】:
1、首先要理解一点,函数是一种叫做function引用类型的实例,因此函数是一个对象。对象是保存在内存中的,函数名则是指向这个对象的指针,是指针。
2、所以基于这一点,将函数名赋值给一个变量,相当于变量存贮的是函数这个对象的指针。而如果函数名后面加上圆括号就表示立即调用(执行)这个函数里面的代码(花括号部分的代码)。下面的例子:
function fun(){
return 5
}
var a=fun //a是fun函数;(不加括号可认为是查看函数完整信息,即查看整个函数体,返回值即整个函数体,不加括号传参相当于传入函数整体)
var b=fun() //b是返回值5;(加括号表示传入函数的返回值);
再来一个例子:
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<script>
var oBtn1 =document.getElementById("btn1");
var oBtn2 =document.getElementById("btn2");
oBtn1.addEventListener("click",fn1)
oBtn2.addEventListener("click",fn2());
function fn1(){
alert("通过点击弹出")//点击btn1,点一次弹出一次。
}
function fn2(){
alert("立即弹出") //页面加载后立即弹出了,点击btn2也是不会再次弹出的。
}
</script>
来自网上的一个例子,我觉得能理解这个例子的话,就真的理解了:
function hi(){
var a = 1;
return function(){
console.log(a++);
};
};
var aaa = hi();
var bbb = hi;
aaa();
aaa();
bbb();
/**答案:aaa 是将 hi() 的运行结果赋值给它,即 return 返回的匿名函数,此时有一个闭包,则每次调用 aaa 时都访问的同一个 a,aaa() 第一次运行结果为 1,第二次为2
而 bbb 将是将 hi 这个函数名赋值给它,则调用 bbb() 后返回一个函数表达式,即function(){console.log(a++)};*/
再下面是使用setInterval时的情况:
function fun() {alert(1);}
setInterval("fun()",2000);//全局作用域下正常执行
setInterval(fun(),2000); //调用函数正常,setInterval调用出错
setInterval(fun,2000); //正确
第一种:【setInterval(“fun()”,2000);】这种加引号的调用就可以理解为“可执行代码” ,就行eval 一样去执行。第一个参数,就是对fun方法的调用 。但是但是,这只能在全局作用域下使用,在window.onload下会报错,就是作用域的问题:
window.onload=function () {
function fun() {
alert(1);
}
setInterval("fun()",2000);//执行报错:(program):1 Uncaught ReferenceError: fun is not defined
}
第二种:【setInterval(fun(),2000); 】这种的话fun函数只会执行一次,在定时器还没开始就执行了,原因就是跟最前面的说的一样,加括号的函数作为参数,直接执行函数体,所以没有什么意义。
第三种:【setInterval(fun,2000);】这种是使用定时器比较常用的正确调用,每隔两秒执行一次fun函数。
总结起来:函数作为参数,加括号的,有返回值的就返回返回值,没有返回值的就是立即执行函数体;不加括号的,传的是函数的位置,即指针。