1.函数的概念
在JS中,函数可以理解为一段在程序(页面)中 多次出现的代码段 封装起来的盒子
简单来说,JS的函数就是一个盒子,盒子里面装的是 在当前页面中 多次出现的 较为复杂的代码段
2.函数的使用
- 函数的定义(创建一个所谓的盒子)
- 声明式定义
语法: function fn(){}
function:关键字 -> 表明后续的是一段函数
fn: 函数的名字 -> 将来函数调用的时候需要用到,函数名自定义
(): 内部填写参数
{}: 内部填写函数调用时要执行的代码段
function fn1(){
console.log('我是fn1函数')
}
- 赋值式定义
语法: var fn = function(){}
var fn2 = function(){
console.log('我是fn2函数')
}
- 函数的调用(使用盒子内的代码) 如果函数只定义不调用那么没有任何意义
- 调用语法: 函数名() / 变量名()
fn1()
fn2()
//间隔500行代码
fn1()
- 声明式和赋值式的区别
- 写法不同
- 调用上略有不同
- 声明式定义的函数,可以在函数定义前去调用
- 赋值式定义的函数,不可以在函数定义前去调用(原因:赋值式定义,其实就是声明一个变量,然后给他赋值为一个函数.在JS中,如果在定义变量之前使用变量的话,那么变量的值为undefined(变量提升))
3.函数的参数
- 函数的参数如何书写?
书写在function后的小括号内
- 参数的作用?如果一个函数没有书写参数,那么这个函数的功能相对来说比较单一;如果书写了参数,能够使我们这个函数的使用更加灵活
参数的书写,分为两个
-
1.function后的小括号内 书写的参数我们叫做"形参"
形参的作用:书写之后,相当于在函数内部创建了一个变量,变量实际的值由"实参"传递
-
2.函数名后的小括号内 书写的参数我们叫做"实参"
实参的作用:将自身的值,按照一一对应的关系,传递给形参
function fn2(a,b){
var sum = a + b
console.log(sum)
}
fn2(10,20)
//新需求:计算300+400的值
fn2(300,400)
- 函数的参数的注意事项:形参和实参 两个的数量,要一一对应
- 1.形参的数量如果大于实参:会将实参按照顺序一一传递给对应的形参;多出来的形参,相当于变量只定义没赋值,所以他们的值是undefined
- 2.实参的数量如果大于形参:会将实参按照顺序一一传递给对应的形参,多出来的实参无法在函数内部通过参数的方式调用
function fn(a,b,c,d){
console.log(a,b,c,d)
}
fn(1,2) //1,2,undefined,undefined
function fn(a,b){
console.log(a,b)
}
fn(100,200,300,400) //100,200
- 3.函数参数的默认值
- 函数在创建形参的时候,默认给一个值,将来在调用的时候,如果没有传递那么这个形参的值也不会是undefined而是给的默认值;如果传递了对应的值,那么形参的指是实参传递进来的,否则按照默认值来运行
function fn(a = 100,b = '我是形参b'){
console.log(a,b) //1,2
}
fn(1,2)
4.函数的返回值(函数的执行结果)
JS有一个规定,在函数内部定义的变量只能在函数内部使用,我们如果想在函数外部得到函数内部的某一个值,或者运算结果,我们可以通过return这个关键字来帮我们完成
function fn(a,b){
var sum = a + b
//书写返回值
return sum
}
//创建变量 接收函数的返回值
var num = fn(100,200)
console.log('num的值:',num) //300
-
return的注意事项
return具有中断函数的能力,所以一般来说我们将它放在函数的尾部
5.函数案例
5.1要求封装一个函数,这个函数能够计算一个区间内所有数字相加的合
function fn(start,end){
//计算1-100之间所有数字的和
var sum = 0
for(var i = start; i <= end; i++){
sum += i
}
return sum
}
var num = fn(1,100)
console.log(num) //5050
5.2判断一个数字!!!是否为水仙花数,是水仙花数,返回一个true,否则返回false
function fn(i){
var baiW = parseInt(i/100)
var shiW = parseInt(i/10%10)
var geW = i % 10
var sum = baiW*baiW*baiW+shiW*shiW*shiW+geW*geW*geW
if(sum===i){
return true
}else{
return false
}
}
fn(153)
var re = fn(152)
console.log(re) //true
6.函数的预解析
预解析的一个表现就是 声明式函数在定义前可以被调用
预解析是什么?
JS在执行代码的时候,会有一个所谓的解析阶段,解析阶段,做了一件事,就是函数提升,就是将声明式函数的定义,提升到当前作用域的最顶端
fn()
function fn(){
close.log('我是 fn 函数,我被调用了')
}
预解析之后的代码:
function fn(){
close.log('我是 fn 函数,我被调用了')
}
fn() //所以此时调用的时候,因为fn 函数已经定义完成了,所以这里能够正常执行函数
7.作用域
-
什么是作用域?
就是变量可以起作用的范围
-
作用域分为哪些?
1.全局作用域(直接在script内书写的代码)
在此作用域创建的变量,我们叫做全局变量,在当前script标签内的哪里都能使用
在JS中,全局作用域中有一个提前给我们准备好的 对象,这个对象叫做 window,我们创建的全局变量,会被自动添加到window对象中
2.局部作用域(在JS中,只有函数能够创建局部作用域)
在此作用域创建的变量,只能在当前作用域使用,超出这个作用域(也就是在函数外边)去使用,就会找不到变量 复制代码
function fn(){
var sum = '我是在函数内部创建的文件,我是局部变量,所以我只能在当前函数内使用'
var abc123 = '我实在fn函数内部创建的局部变量'
console.log(sum)
}
fn()
// console.log(sum)//这里因为超出了这个变量的使用区间,所以会报错
var abc = '我是一个全局变量abc'//创建一个全局变量abc
console.log(window)
8.作用域链
- 概念
作用域链就是在访问一个变量的时候,如果当前作用域内没有,会去自己的父级作用域,也就是上一层作用域内查找,如果找到就直接使用,如果没有找到继续向上层查找,直到查找到 最顶层的全局作用域,如果找到了直接使用,如果没有找到,报错提示变量不存在(未定义),我们将这个一层一层向上查找的规律,叫做作用域链.
var num = 999
function fn1(){
var num = 100
function fn2(){
console.log(num)
/**
* 打印的值为100
* 1.现在现在当前作用域内,也就是 fn2 函数内部开始查变量 num,然后发现 当前作用域内 没有这个变量 所以会去自己的父级的作用域内查找( 也就是 fn1 这个函数内部)
* 2.来到了自己的父级内部查找,此时找到了一个变量num 他的值为100,然后直接使用这个变量
*/
}
fn2()
}
fn1()
var num = 999
function fn1(){
function fn2(){
console.log(num)
/**
* 打印的值为999
* 1.现在现在当前作用域内,也就是 fn2 函数内部开始查变量 num,然后发现 当前作用域内 没有这个变量 所以会去自己的父级的作用域内查找( 也就是 fn1 这个函数内部)
* 2.来到全局作用城内查找的时候 发现了一个叫 num 的变量值为 999,然后停止查找,直接使用该变量
*/
}
fn2()
}
fn1()
- 作用域链的赋值规则 在给变量赋值的时候,首先会去当前作用域内查找该变量,如果有,直接赋值,并停止查找;如果没有,会去自己的父级查找,在父级找到直接修改然后停止查找,如果没有继续向自己的父级查找,直到找到全局作用域,在全局作用域内,找到直接赋值修改他的值,如果没有找到,那么会在全局作用域创建一个变量,并赋值.
function fn1(){
var num = 999
function fn2(){
num = 100
/**
* 在当前作用域内查找,发现没有,会去自己的父级作用域内查找也就是fn1函数内部
* 在fn1函数内部发现一个变量num 然后值为999 我们会对这个变量做一个重新赋值的操作
* 也就是将他的值 重新修改为100
*/
}
fn2()
console.log(num)//100
}
fn1()
9.递归函数
当一个函数在函数的内部,调用了自身,那么就算是一个所谓的递归函数(只不过有点小缺陷)
function fn(n){
if(n === 1){
//说明此时想要计算1的阶乘,那么我直接将1的阶乘的结果return出去
return 1
}
return n * fn(n - 1)
}
var sum = fn(4)
console.log(sum) // 24
var sum1 = fn(100)
console.log(sum1)