函数(上)0805
---
typora-root-url: img
---
# 变量内存分布
## 内存地址解释
计算机中运算是在CPU中进行的,但是数据是保存在内存条中,编程语言中每一个变量都可以存储一些数据,数据
最后就存储到内存中。对于内存的管理由操作系统(window)完成。在管理内存过程中会将内存条进行划分。在划
分内存时,每一个小区域都设置了一个数字(标识),这个标识就是**内存地址**,可以通过内存地址快速定位内存中内
容。
## 基本数据类型
"内存在被划分为一个个小的内存地址之前",会先划分为多个大的区块.目前只关注两个 分别是堆区、栈区
堆区:相对栈区 空间大,但是速度慢
栈区:相对于堆区 空间小,但是速度快
```javascript
// 1、任何一个变量 都会使用栈区的空间
var number = 10;
// 创建一个n变量 就是在栈区中开辟一个空间 只是这个空间目前存储的值是undefined
var n ;
// 将number变量的值赋值给n(将number变量栈区中存储的值赋值给n) 一定要记住 变量赋值 永远是将栈区的值进行赋值操作
n = number;
// 将number变量栈区的值修改为20
number = 20;
console.log(n,number)
```
内存图
![1659664409397](/1659664409397.png)
## 引用数据类型
```javascript
// 先在栈区创建一个变量(空间),将数据保存到堆区,再讲堆区的内存地址记录到栈的空间中
var arr = [1, 2, 3];
// 将arr变量栈区的内存地址赋值给a变量保存
var a = arr;
// 顺着arr的内存地址将堆区中1号元素的数据修改为200
arr[1] = 200;
console.log(a);
```
![1659665147903](/1659665147903.png)
```javascript
var arr2 = [1, 2, 3];
var b = arr2;
// 表示顺着堆区的地址将堆区中的数据改掉
// arr2[1] = 200
// 将arr2变量赋值为20 赋值语句永远改的是栈区中的内容
arr2 = 20;
console.log(b);
```
# 函数
## 函数的作用
例如现在实现功能目前已经写了190行代码。但是项目中可能多个位置需要再次使用这个功能。所以需要将190行
代码再次重复,所以导致代码重复了。解决方式使用函数。**函数的最大特点就是一次定义多次调用**
## 函数的理解
可以将函数理解为洗衣机
很多时候 可以直接使用系统中内置函数(洗衣机已经造好了,直接使用即可)。也可以自己创建函数(自己造了洗衣
机)
洗衣机使用方式,只要原料足够 只需要按下开关即可(函数只要调用,内部的代码就会自动执行起来)
原料在函数中就是参数。洗衣机最后运行完毕。可以得到干净的衣服(函数运行完毕,可以使用变量接受返回值)
## 函数的定义与调用
1、语法
```javascript
创建函数
1、声明式 [函数参数] 表示可选 不是数组
function 函数名称([函数形参]){
//函数体代码
//选择性的使用return语句
}
2、赋值式
var 变量名称 = function([函数形参]){
//函数体代码
//选择性的使用return语句
}
调用函数
函数名称([函数实参])
```
2、使用示例
```javascript
// 创建了叫做login的函数 没有参数
function login(){
console.log('验证用户名');
console.log('验证密码');
}
// 调用函数
login();
login();
login();
login();
```
## 声明式与赋值式的区别
```html
<script>
// 代码是按照从上向下执行的并且按照script标签段执行的 先执行完一个script标签中代码,然后在执行下一个script标签
// a();// ReferenceError: a is not defined(a未定义)
</script>
<script>
a();
// b(); b is not a function(b有定义 但是不是一个函数)
// 声明式创建的函数
function a(){
console.log('声明式')
}
a();
// 赋值式创建的函数
var b = function(){
console.log('赋值式')
}
b();
// 在同一个script标签中 声明式函数 可以在任何位置调用 但是赋值式只能在创建之后使用
</script>
<script>
a();
</script>
```
## 函数的参数
### 形参与实参
1、参数的位置区分
```javascript
在函数定义中所写的就是形参,形参没有名称要求,但是实际使用时经常会使用跟实参同名的名字
调用函数时所使用的就叫做实参
参数可以理解为洗衣机中各种原料
```
2、基本使用
```javascript
// sum函数用于对两个数字进行求和计算
// 当使用函数时 一切不确定的信息 全部设置为参数
// 多个参数之间使用逗号分割
function sum(a,b){
// var a = number1;var b = number2; 隐藏操作,系统自动运行,一旦调用函数,系统会自动将实参的参数值按照顺序赋值给形参
console.log(a,b);
console.log(a+b);
}
var number1 = 30;
var number2 = 20;
sum(number1,number2);
```
3、传递基本类型
```javascript
function fn(a){
// var a = number3; 将number3在栈区存储的值赋值给a变量。a与number变量 都是单独的。所以互不影响。
a= 100;
}
var number3 = 40;
fn(number3);
console.log(number3);
```
4、传递引用类型
```javascript
// 传递引用类型
function fn2(a){
// var a = arr; 将arr栈区存储的堆区地址赋值给了a变量
// a[1] = 200 将堆区的1号元素值修改为200
a[1] = 200;
}
var arr = [1,2,3];
fn2(arr);
console.log(arr);
```
5、关于函数中变量的使用范围
```javascript
function fn3(b){
// var b = number3;
var n = 10;
}
fn3(number3);
console.log(n);//n is not defined 因为n变量是在函数调用过程中创建的变量。一旦函数运行完毕 内部的所有变量默认情况下全部被回收(垃圾回收机制)
```
### 可变参数
一般形参与实参个事对应,但是部分场景下形参与实参的个数无法对应起来,例如需要计算任意个数参数的和。无法确定具体需要设置几个形参。所以可以使用可变参数
1、形参比实参多情况
```javascript
// 1、形参比实参多情况 还是会按照顺序实参赋值给形参,但是多的形参都是undefined
function fn(a,b){
// var a = 10; var b ;
console.log(a,b)
}
fn(10)
```
2、形参比实参少情况
```javascript
// 2、形参比实参少情况,也会按照顺序赋值,多余的实参在函数体中没有直接变量可以对应起来.
function fn2(a){
console.log(a);
}
fn2(10,20)
```
3、可变参数
```javascript
// 可变参数
function sum() {
// arguments 内置所提供的伪数组(元素从0下标开始并且也有length长度,形式向数组但是不是数组)。arguments每一个元素就对应着每一个实参 每一个function式的函数(声明式或者赋值式) 内置都有
// console.log(arguments);
var total = 0;
for (var i = 0; i < arguments.length; i++) {
total += arguments[i];
}
console.log(total)
}
sum(1, 2, 3, 50);
//arguments取参数尽量少用。平常封装函数都是使用有名称的形参表示
```
## 函数的返回值
### 结束函数代码执行
```javascript
function sum(a,b){
// 需求 如果b比a的值大 就不计算求和的结果
if(b>a){
// 只要在函数中代码运行到return语句,不论后面还有多少代码都终止了
return;
}
var total = a + b;
console.log('a+b');
}
sum(10,20)
```
### 返回数据给调用者
```javascript
function sum(a,b){
// 需求 如果b比a的值大 就不计算求和的结果
if(b>a){
// 只要在函数中代码运行到return语句,不论后面还有多少代码都终止了
return;
}
var total = a + b;
return total;
}
// 将sum函数执行,并且将return的结果赋值给res变量
var res = sum(10,8);
console.log(res);
var res2 = sum(10,20);//函数不return数据 最终接受的结果就是undefined
console.log(res2)
```