js第n+3天
函数
函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
语法: function 函数名(){}
<script>
function 函数名(params) {
函数体
}
</script>
命名规划: 和变量命名基本一致 尽量小驼峰式命名法 前缀应该为动词 命名建议:常用动词约定
函数的调用
定义了一个函数,使用时要调用,不调用的话,函数没有任何作用
语法: 函数名()
<script>
//定义函数
function sayHi() {
document.write('嗨')
}
//调用函数
sayHi()
</script>
练习1
写一个打招呼的函数 hi~,重复三次
<script>
//定义函数
function sayHi() {
document.write('嗨')
}
//调用函数
//调用几次写几次
sayHi()
sayHi()
sayHi()
</script>
练习2
封装一个函数,计算两个数的和
<script>
function getNum() {
let num1 = 1
let num2 = 1
document.write(num1 + num2)
}
getNum()
</script>
函数传参
为什么要有参数的函数 思考:这样的函数只能求 10 + 20, 这个函数功能局限非常大
<script>
function getNum() {
let num1 = 10
let num2 = 20
document.write(num1 + num2)
}
getNum()
</script>
解决办法:把要计算的数字传到函数内 结论 若函数完成功能需要调用者传入数据,那么就需要用有参数的函数 这样可以极大提高函数的灵活性
语法:
function 函数名(参数){函数体}
<script>
//这样定义参数,再把内容输入到参数,就变得很灵活
function getNum(num1,num2) {
document.write(num1 + num2)
console.log(num1 * num2)
}
</script>
声明函数后,调用函数
<script>
function getNum(num1,num2) {
document.write(num1 + num2)
console.log(num1 * num2)
}
//在调用时输入对应的函数,用逗号隔开
getNum(10,30)
</script>
形参和实参
声明函数时写在函数名右边小括号里的叫形参(形式上的参数) 调用函数时写在函数名右边小括号里的叫实参(实际上的参数) 形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
练习3
需求:采取函数封装的形式:输入2个数,计算两者的和,打印到页面中
<script>
function getNum(num1,num2) {
document.write(num1 + num2)
}
getNum(1,3)
</script>
练习4
需求:学生的分数是一个数组,计算每个学生的总分
<script>
function getNum(arr) {
let sum = 0
for (let index = 0; index < arr.length; index++) {
sum += arr[index]
}
document.write(sum)
}
let arr1 = [2,4,123,31,41]
getNum(arr1)
</script>
函数返回值
函数是被设计为执行特定任务的代码块, 把任务的结果给我们
缺点:把计算后的结果处理方式写死了,内部处理了 解决:把处理结果返回给调用者
语法:
<script>
function getNum(num1,num2) {
return num1 + num2
}
let num = getNum(10,30)
document.write(num)
console.log(getNum(10,30))
</script>
细节: 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用 函数内部只能运行到 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写 return会立即结束当前函数 函数可以没有 return,这种情况函数默认返回值为 undefined
练习5
求任意2个数中的最大值并返回这个最大值
<script>
function getMax(num1,num2) {
let num = num1 > num2 ? num1 : num2
return num
}
document.write(getMax(10,30))
console.log(getMax(60,10))
</script>
练习6
求任意数组中的最大值并返回这个最大值
<script>
function getMax(arr) {
let max = [0]
for (let index = 0; index < arr.length; index++) {
if (arr[index] > max) {
max = arr[index]
}
}
return max
}
let arr1 = [2, 3, 41, 231, 4, 653]
document.write(getMax(arr1))
</script>
作用域
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
全局变量 全局变量在变量定义之后区域可以访问和修改
<script>
//写在script里的没有被其他包裹的,就为全局变量
//全局变量在其他区域也能使用
let num = 100
//没有声明,直接赋值,也是全局变量,但是强烈不推荐,而且不受其他影响,永远是全局变量
num = 200
</script>
局部变量
<script>
function name(params) {
//写在函数里面的变量为局部变量,或者叫函数变量,函数内部有效
let num = 100
}
</script>
块级变量
<script>
//在for,while,num 里面的变量都为块级变量,{}里面有效
for (let index = 0; index < array.length; index++) {
let num = 100
}
while (condition) {
let num = 100
}
if (condition) {
let num = 100
}
</script>
作用域链
只要是代码,就至少有一个作用域 写在函数内部的局部作用域 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
就近原则
就近原则是以函数的声明、函数的定义来寻找最近的变量
匿名函数
将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式
语法:
<script>
let fn = function(){}
//调用匿名函数
fn()
</script>
立即执行函数
场景介绍: 避免全局变量之间的污染
语法:
<script>
//两个括号,第一个括号里面加匿名函数
(function () {console.log(11)}) ()
</script>
防止变量污染 无需调用,立即执行,其实本质已经调用了