# 函数

函数在程序中代表的就是一段具有功能性的代码，可以让我们的程序编程更加具有结构性和提升程序的复用性,也能让代码变得更加灵活强大。

### 函数声明

```javascript
/*
// 函数的定义方式1
function 函数名 (参数){
    函数体;
    return 返回值;
}
功能说明：
    可以使用变量、常量或表达式作为函数调用的参数
    函数由关键字function定义
    函数名的定义规则与标识符一致，大小写是敏感的
    返回值必须使用return
    
//  函数的定义方式2
    
用 Function 类直接创建函数的语法如下：
var 函数名 = new Function("参数1","参数n","function_body");

虽然由于字符串的关系，第二种形式写起来有些困难，但有助于理解函数只不过是一种引用类型
*/
```

### 函数调用

```javascript
//f(); --->OK
function f() {
    console.log("hello")

}

f() //----->OK
```

> 不同于 Python，JS 代码在运行时，会分为两大部分 ——— 检查装载 和 执行阶段。
>
> * 检查装载阶段：会先检测代码的语法错误，进行变量、函数的声明
> * 执行阶段：变量的赋值、函数的调用等，都属于执行阶段。

### 函数参数

#### 参数基本使用

```javascript
// 位置参数
function add(a, b) {

    console.log(a);
    console.log(b);
}

add(1, 2)
add(1, 2, 3)
add(1)


// 默认参数
function stu_info(name, gender = "male") {
    console.log("姓名：" + name + " 性别：" + gender)
}

stu_info("bobo")
```

### 函数返回值

在函数体内，使用 return 语句可以设置函数的返回值。一旦执行 return 语句，将停止函数的运行，并运算和返回 return 后面的表达式的值。如果函数不包含 return 语句，则执行完函数体内每条语句后，返回 undefined 值。

```javascript
function add(x, y) {
    return x, y
}

var ret = add(2, 5);
console.log(ret)
```

> 1、在函数体内可以包含多条 return 语句，但是仅能执行一条 return 语句
>
> 2、函数的参数没有限制，但是返回值只能是一个；如果要输出多个值，可以通过数组或对象进行设计。

### 函数作用域

作用域是 JavaScript 最重要的概念之一。

JavaScript 中，变量的作用域有全局作用域和局部作用域两种。

**局部变量**：是在函数内部声明，它的生命周期在当前函数被调用的时候,，当函数调用完毕以后，则内存中自动销毁当前变量

**全局变量**：是在函数外部声明，它的生命周期在当前文件中被声明以后就保存在内存中，直到当前文件执行完毕以后，才会被内存销毁掉

首先熟悉下 var

```javascript
var name = "bobo"; // 声明一个全局变量 name并赋值”bobo“
name = "张三";  // 对已经存在的变量name重新赋值 ”张三“
console.log(name);

var gender = "male"
var gender = "female" // 原内存释放与新内存开辟，指针指向新开辟的内存
console.log(gender)
```

作用域案例：

```javascript
var num = 10; // 在函数外部声明的变量, 全局变量
function func() {
    //千万不要再函数内部存在和全局变量同名的变量
    num = 20; // 函数内部直接使用变量,则默认调用了全局的变量,
}

func();
console.log("全局num：", num);
```

### 匿名函数

匿名函数，即没有变量名的函数。在实际开发中使用的频率非常高！也是学好 JS 的重点。

```javascript
// 匿名函数赋值变量
var foo = function () {
    console.log("这是一个匿名函数！")
};
foo() //调用匿名函数


// 匿名函数的自执行
(function (x, y) {
    console.log(x + y);
})(2, 3)


// 匿名函数作为一个高阶函数使用
function bar() {

    return function () {
        console.log("inner函数！")
    }
}

bar()()
        
```
