一、函数的创建
函数的创建有以下三种写法
<script>
//声明式函数
function 函数名(形参1,形参2...){执行的代码块}
//变量赋值式函数
var 变量名 = function(形参1,形参2...){执行的代码块}
//调用函数
函数名或变量名(实参1,实参2...);
//匿名函数以及调用(因为没有函数名,相当于自己调用自己),三种写法
//第一种,感叹号开头,最后接一对小括号
!function(形参1,形参2...){执行的代码块}()
//第二种,用小括号将函数整体包起来,并在最后接一对小括号
(function(形参1,形参2...){执行的代码块})()
//第三种,函数最后接一对小括号,并用一对小括号将整个包起来
(function(形参1,形参2...){执行的代码块}())
</script>
注意:
1.调用函数时,函数名后面的()不可少,()相当于执行函数,而没有()相当于打印函数整体
2.当实参比形参少的时候,没有对应实参的形参,默认为undefined
二、返回值(return)
在函数内部定义的变量为局部变量,在函数外无法获取,想要局部变量的值时,就需要return来返回这个变量的值给函数外。
<script>
function fn1(a){
console.log(a);
return 5;
console.log(a);
}
console.log(fn1(3));
</script>
可以看到,return之后会停止当前函数程序,return之后的代码不会执行
return之后的值相当于把调用函数fn1(3)替换成了5
三、预解析
在js中,会把定义变量和定义函数放在该作用域内的最前面执行。
注意:
1.定义变量并赋值只会把定义变量提前,而赋值操作不会提前
2.定义函数会整个提前,当有同名函数时,后者会覆盖前者
3.变量赋值式函数,就是把函数赋值给变量,所以变量提前而那个函数不会提前,就会出现以下情况
<script>
fn1()
var fn1 = function(){
console.log(6);
}
</script>
4.当变量和函数名相同时,函数优先提前
四、作用域
局部作用域:
在函数的内部声明的变量只能在内部使用,外部无法调用
全局作用域:
在函数外部声明的变量,在函数内部也可以使用
特殊情况:
在函数内部声明变量没有使用var关键字,则会向函数外查找,相当于定义了全局变量
查找变量的一些规则:
1.如果当前作用域有定义的时候就会直接使用当前作用域中的变量
2.如果当前作用域中没有定义就会往上级查找 ,上级没有继续往上查找,直到找到全局
3.如果全局有的话就直接输出 ,全局没有的话直接报错
五、函数递归
<script>
function fn1(){
fn1();
}
fn1();
</script>
以上就是函数的递归,可以看出,函数内部调用了自己,就会形成类似于循环,没有终止条件的话会无限循环。
该写法会在栈内生成多个fn1(),堆内生成多个function函数,影响内存
<script>
function fn1(){
return fn1();
}
fn1();
</script>
而这个写法利用return返回值替换fn1(),就不会在栈内生成多个,节省内存。