目录
一、函数定义
二、函数声明的方法
1、命名函数 (自定义函数)
2、匿名函数
三、函数return语句
四、函数的参数
函数形参和实参
函数参数对应关系
五、函数表达式
具名函数与函数表达式区别
预解析
六、变量的作用域
七、立即执行函数
八、函数练习
1、封装余额函数
2、求和封装函数
3、实现两个值的交换
4、封装⼀个函数,可以求任意数组的和 或 平均值
5、封装函数-判断某个元素在不在数组中在的话返回true,不在返回false
函数是具有某种功能的代码块,为了复用。
定义
function 函数名() {
// 具体功能的代码实现
}
语法: function 函数名(){
// 函数体
}
var 变量名 = function(){
//函数体
}
函数名最好使用动词、有意义的,如果多个单词组成需要驼峰命名 myName
function是声名函数的关键字 需要小写
函数自身不会执行,需要调用后才会执行函数内的代码
函数分为两步:1、声明函数 2、调用函数
return 作用-返回一个值,并且可以让函数提前结束调用
语法 1 return sum 不能写成
return
sum
return下面的代码不执行
return后面加上值,可以把值返回出来,如果值用逗号隔开的,值能返回最后一个值,如果值 是数组就返回数组;如果值是x+y这种,
返回值是x+y的结果
结束当前循环,可以返回值,可以结束函数体内的代码
函数return值后,调用函数时,就已经拿到了return的这个值
// 一个函数没有return语句 默认返回undefined
function f() {
// 函数体 空函数体
}
console.log(f())
求两个数的和
// 求两个数的和
// 函数声明的时候x,y叫形式参数-形参
function add(x, y) {
const sum = x + y
return sum // 返回sum
// console.log('hello')
}
// 调用 函数调用的时候,叫实际参数-实参
// 实参传递给形参,一一对应传递
let result = add(1, 2) // add(1,2) 调用函数拿到返回值赋值给result
console.log(result)
//add(3, 4)
形参: 虚拟,是声明函数时写在函数名后的小括号内,参数之间使用逗号隔开,形参时使用变量名接收
实参: 真实,是调用函数时写在小括号内的参数,参数之间使用逗号隔开
形参和实参是一一对应的关系,如果形参没有实参对应,形参拿到的就是undefined
// 求两个数的和
// 函数声明的时候x,y叫形式参数-形参
function add(x, y) {
console.log(x + y)
}
// 调用 函数调用的时候,叫实际参数-实参
// 实参传递给形参,一一对应传递
//add(1, 2)
//add(3, 4)
函数的参数是一 一对应的
多余的形参默认undefined
多余的实参被忽略
function add(a, b) {
console.log(a, b)
return a + b
}
console.log(add(1, 2))
console.log(add(1)) // NaN // 多余的形参默认undefined
console.log(add(1, 2, 3)) // 多余的实参被忽略
匿名函数-函数表达式
let fn = function () {
console.log('hello world')
}
fn()
fn()
普通函数可以先调用后声明
js代码在执行的时候,分为预解析(把var定义变量或函数声明拿到代码最前面)和代码执行
函数表达式必须先声明才调用
1、遇到var 和function 先预解析
2、代码执行
var :js解析器遇到var时,会先变量提升,提升到当前作用域的最上方,变量赋值的位置保持不变,然后再进行代码执行
函数预解析 : js解析器遇到function会把整个函数提升到当前作用域的最上面,其他代码还是原来的位置
函数调用要看清是否调用以及调用的顺序时否正确
预解析 不会把const或let定义的变量进行提升
fn2()
const fn2 = function () {} // 必须有函数才能调用
作用域-----变量或函数的使用有效范围
分类: 全局作用域、局部作用域(函数作用域 、块级作用域)
全局作用域:script标签或js文件
局部作用域-函数作用域
全局作用域:在整个script脚本里就是全局作用域
局部作用域:在函数内就是局部作用域
全局变量:在script脚本内的变量都是全局变量,全局变量只有浏览器关闭时才会销毁释放内存
在全局作用域内定义相同的变量会被覆盖
局部变量:函数内的变量也叫局部变量,函数使用结束后就会立即销毁释放内存
局部作用域声明的变量和全局变量互不干扰,在全局作用域内是不能访问局部变量的
在局部作用域内是可以访问全局变量的
//局部作用域-函数作用域
function f() {
let i = 100 // 局部变量 只能在所在的函数内使用
}
f()
console.log(i) // 报错
局部作用域-块级作用域
// 局部作用域-块级作用域
{
let i = 100 //在 {} 定义的变量只能在 {}内部使用
console.log(i)
}
console.log(i)
变量的使用原则:就近原则
let num = 10
function f() {
//let num = 20
num++
console.log(num) //20 就近原则
}
f()
console.log(num) // 10
特殊情况:在局部作用域下不使用var声明的变量是全局变量(不推荐)
函数的形参也是局部变量
作用域链:一级一级朝上查找变量,自己作用域没有就会朝外面的作用域查找
函数嵌套函数时,每一个函数都是独立的作用,里层函数可以访问外层函数的变量
外层函数不能访问里层函数的变量
变量之间也是互不影响
变量查找时遵循就近原则(只对里层函数朝外层查找)
IIFE -立即调用函数表达式
第一种形式 (function() { ...})()
(function () {
console.log(111)
})()
第二种形式 (function(){}())
多个自执行函数用分号隔开
// 多个自执行函数用分号隔开
;(function () {
console.log(123)
})()
;(function () {
console.log(456)
})()
自执行函数应用场景-防止变量全局污染
封装库或框架使用,这样让变量不会与其他的变量 冲突
function changeNum(a,b){
let temp=a
a=b
b=temp
return `${a},${b}`
}
console.log(changeNum(1,2)) //2,1
console.log(changeNum(3,2)) //2,3
函数可以传递2个参数,⽐如 handleData(arr, true) handleData 处理数据的意思
参数⼀: 接受实参传递过来的数组
参数⼆: 布尔类型 如果是true或者不传递参数 是求和操作, 如果传递过来的参数是 false
则是求平均值
function handleData(arr,flag=true) {
// flag = true
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
if(flag){
return sum
}else{
return sum/arr.length
}
}
const arr = [1, 2, 3, 4, 5]
console.log(handleData(arr,true))//15
console.log(handleData(arr))//15
console.log(handleData(arr,false))//3
function findEleInArr(ele,arr){
let result=false //定义变量存储结果
for(let i=0;i