01-函数类型
1.0-函数介绍
-
1.在实际开发中,我们有很多功能代码 并
不是只执行一次,而是需要在很多个地方。- 例如我们之前学习过的求和功能 :购物车页面需要求和,自己的订单列表页面需要求和查看总消费,还有待付款页面等等
- 多个地方:可以是同一个程序员好多个页面都需要使用。 也可以是不同程序员所负责的页面
-
2.那么既然是相同的功能代码,我们肯定不能复制粘贴去写冗余代码。这样万一功能有变化,维护起来就会很不方便
-
3.而函数就是解决这些重复功能的
代码复用问题- 函数是一个数据类型,可以理解为存储代码的容器。 把这些代码给存到变量中,要使用的时候取出来执行即可。
<script>
需求:一段代码 需要在很多个地方使用
函数语法
1.声明函数 : 是一个存储过程,此时不会执行函数体代码
function 函数名(){
函数体代码: 需要存储的一段代码
}
2.调用函数 : 执行函数体代码
函数名()
1.声明函数 : 把代码存入容器中
function fn() {
console.log("hello world")
}
2.调用函数: 执行函数体代码
调用者A
fn()
</script>
1.1-函数声明/调用
<script>
一段代码 需要在很多个地方使用
函数语法
1.声明函数 : 是一个存储过程,此时不会执行函数体代码
function 函数名(){
函数体代码: 需要存储的一段代码
}
2.调用函数 : 执行函数体代码
函数名()
1.声明函数 : 把代码存入容器中
function fn() {
console.log("hello world")
}
2.调用函数: 执行函数体代码
调用者A
fn()
调用者B
fn()
</script>
1.2-函数参数
<script>
0.函数语法: 函数是一种用于存储代码块的复杂数据类型
* 作用:解决代码复用问题
1.声明函数 : 声明函数只是把代码存起来,不会执行函数体
function 函数名(){
函数体代码: 需要存储的一段代码
}
2.调用函数 : 执行函数体代码
函数名()
3.函数参数 : 调用者 传递数据 函数
3.1 传:调用者
函数名(实际参数)
3.2 收:函数
function 函数名(形式参数){ //函数体代码 }
3.3 函数传参本质: 实参给形参赋值的过程
(1)函数传参是按照传入顺序一一赋值
(2)函数每一次调用传参过程都是独立的,互不影响
(3)函数 形参数量 和 实参数量 可以不一致的
声明函数
function fn(x,y) {
console.log(x,y)
}
调用函数
调用者A
learn(10,20)
调用者B
learn(30,40)
</script>
1.3-函数默认参数(逻辑短路运算)
<script>
1.函数默认参数,我们自己在开发中使用不多。(了解后面很多js框架函数默认参数底层原理)
2.函数默认参数 使用 逻辑运算符短路运算(逻辑中断)
2.1 短路运算: 左边式子就可以决定结果,右边式子不执行
&& : 一假则假
|| : 一真则真
! : 取反(没有短路运算,因为只有一个式子)
2.2 短路规则:
&& : 找假。 左边式子值可以转成false,则无条件返回左边式子的值,右边不执行。 反之无条件返回右边式子的值。
|| : 找真。 左边式子值可以转成true,则无条件返回左边式子的值,右边不执行。 反之无条件返回右边式子的值。
let res = undefined && 20
console.log( res )//undefined
let res1 = undefined || 20
console.log( res1 )//20
需求:给函数添加默认参数0
(1)如果用户有传递实参,就使用用户传递的实参
(2)如果没有传,就使用默认参数
function getSum(num1,num2){
num1 = num1 || 0
num2 = num2 || 0
console.log(num1+num2)
}
getSum(66)
</script>
1.4-函数返回值
<script>
0.函数语法: 函数是一种用于存储代码块的复杂数据类型
* 作用:解决代码复用问题
1.声明函数 : 声明函数只是把代码存起来,不会执行函数体
function 函数名(){
函数体代码: 需要存储的一段代码
}
2.调用函数 : 执行函数体代码
函数名()
3.函数参数 : 调用者 传递数据 函数
3.1 传:调用者
函数名(实际参数)
3.2 收:函数
function 函数名(形式参数){ //函数体代码 }
3.3 函数传参本质: 实参给形参赋值的过程
(1)函数传参是按照传入顺序一一赋值
(2)函数每一次调用传参过程都是独立的,互不影响
(3)函数 形参数量 和 实参数量 可以不一致的
4.函数返回值 : 函数 传递数据 给调用者
4.1 传:函数
function 函数名(){ return 值 }
4.2 收: 调用者
let 变量名 = 函数名()
4.3 注意点
(1)函数return关键字后面的代码不会执行的
* 只要有return关键字,函数体立即结束执行。
(2)如果函数没有return,则默认返回值undefined
写一个函数,求数组的和
声明函数
function getSum(arr){
let sum = 0
for(let i =0;i<arr.length;i++){
sum += arr[i]
}
返回值
return sum
}
调用者A
let num1 = getSum([10,20,30,40,50])
document.write(num1)
调用者B
let num2 = getSum([80,20,55,66])
document.write(num2)
</script>
03-作用域
1.1-作用域介绍
- 注意:如果一个变量在声明的时候没有使用关键字。 例如:
num = 10,此时这个变量无论写在哪里都是全局变量。 (切忌:这是非常不规范的,千万不要这么写,否则以后代码可能会出现bug)
<script>
1.js变量作用域: 变量可以使用的区域
* 作用:避免变量污染(变量名相同导致代码冲突)
2.js三种作用域
2.1 全局作用域(全局变量) : 在函数外面let的变量
2.2 局部作用域(局部变量) : 在函数里面let的变量
2.3 快级作用域(快级变量) : 在分支或循环大括号中let的变量
1.全局变量
let num = 10
function fn(){
2.局部变量
let age = 18
console.log( num )
console.log( age )
}
console.log(age)//报错。 局部变量只能在函数内部使用,函数外部无法使用
fn()
3.快级变量
if(1){
let sex = '男'
console.log(sex)
}
console.log(sex)
for(let i=1;i<=5;i++){
console.log('循环内部:' + i )
}
console.log('循环外部:' + i)
</script>
1.2-作用域链
<script>
1.js变量作用域: 变量可以使用的区域
* 作用:避免变量污染(变量名相同导致代码冲突)
2.js三种作用域
2.1 全局作用域(全局变量) : 在函数外面let的变量
2.2 局部作用域(局部变量) : 在函数里面let的变量
2.3 快级作用域(快级变量) : 在分支或循环大括号中let的变量
3.作用域链: 默认情况下,代码处于全局作用域(0级链),当声明一个函数之后就会开辟一个局部作用域(1级),而函数里面又可以声明一个函数,又会形成新的作用域(2级),以此类推形成的结构称之为作用域链
4.变量访问规则: 就近原则
* 当你在一个作用域访问变量的之后,首先会看当前作用域有没有声明。如果有则访问。 没有则往上级作用域查找,有没有声明。有则访问,没有则继续往上。直到作用域最顶端0级,如果还没有找到。则程序报错 xxx is not defined
0级
let num = 10
function fn1(){//fn1本身还是0级的,只是里面函数体是1级
//1级
let num = 20
console.log(num)//20
function fn2(){
//2级
let num = 30
console.log(num)//30
}
fn2()
}
fn1()
console.log( num )//10
</script>