[TOC]
* * * * *
### 一、什么是函数
> 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。
- 语法
```JavaScript
function fun(arg1,arg2){
// 要执行的代码块
}
```
- 调用方式
第一种:事件驱动函数
```HTML
<button onClick="fun()">按钮</button>
<script>
function fun(arg1,arg2){
// 要执行的代码块
}
</script>
```
第二种:调用函数
```JavaScript
function fun(arg1,arg2){
// 要执行的代码块
}
fun()
(function (arg1,arg2){
// 要执行的代码块
})()
```
### 二、函数需要了解的知识
1. 作用域
作用域分为全局作用域和局部作用域
全局作用域:供所有代码执行的环境,只要浏览器不关闭就不会消失,也是最高的执行环境,在该作用域下声明的变量为全局变量
局部作用域:函数执行的时候,开辟的用来解析函数体的代码的新的栈内存,它也叫做私有作用域,在该作用域下声明的变量为局部变量
```JavaScript
//变量a就处于全局环境下,它是全局变量
var a = 1;
function fun(){ // 函数fun 处于全局环境下
var b = 2; //变量b就处于局部环境下,它是局部变量
var a = 3; //变量a就处于局部环境下,它是局部变量
}
```
2. 变量
js中使用var声明的东西才是变量,但是需要注意的是:
```JavaScript
var b = 1;
c = 1
```
这里变量b和c的区别是:
- b是变量而c不是变量,要注意的是在全局环境下,变量b和c都会被js引擎添加到window下作为其属性,如果在局部变量下,当函数执行后变量不会被添加到window对象上作为其属性。
- 变量b会在程序初始化是提升(变量提升原则),而c不会。
```JavaScript
console.log(a) // a为underfind,因为a变量初始化时被提升了
var a = 1;
console.log(a) // 1
```
### 三、函数声明和函数表达式
1. 什么是函数声明
> 有一个特定的名称
> 在源码中的位置:要么处于程序级(Program level),要么处于其它函数的主体>(FunctionBody)中
> 在进入上下文阶段创建
> 影响变量对象
以下面的方式声明
```JavaScript
function fun(){
}
```
上边的函数就是以函数声明方式创建的,有一个特定的名称fun,处于全局环境,在进入上下文阶段创建指的是程序开始运行时优先处理函数。影响变量对象可以看下面代码:
```JavaScript
console.log(fun) // fun函数,这里是因为函数提优先于同名变量提升(其实是覆盖了变量对象中的同名变量)
var fun = 111;
console.log(fun) //111
function fun(){
}
console.log(fun) //fun 函数
var fun = 222;
console.log(fun) //222
```
2. 函数表达式
> 在源码中须出现在表达式的位置
> 有可选的名称
> 不会影响变量对象
> 在代码执行阶段创建
最典型的就是匿名函数:
```JavaScript
var fun = function (){}
```
函数表达式其实也可以拥有函数名的:
```JavaScript
!function fun(){} // 这也是函数表达式
```
所以说函数表达式和函数声明最主要的判断依据是,看看函数主体function 最前边是否含有其它东西(主要指运算符)。
例如常见表达式:
```JavaScript
+function fun(){
}
1,function fun(){
}
&function fun(){
}
(function(){})
var obj = {
fun:function(){}
}
```
### 四、立即自执行函数
程序一运行时,函数会立即自己调用自己的函数。常见的立即自执行函数:
```JavaScript
(function(a){
console.log(a) // 1
})(1)
(function(a){
console.log(a) // 1
}(1))
```
自执行函数还有没有其他的写法,其实是有的,我们只要知道立即自执行函数是怎么自调的就可以写出很多,他的特点就是小括号 `()` 左边只要是函数表达式,它就可以立即自调。
例如:
```JavaScript
+function fun(a){
console.log(a) // 1
}(1)
1,function fun(a){
console.log(a) // 1
}(1)
&function fun(a){
onsole.log(a) // 1
}(1)
```