JavaScript 基础第四天 — 函数
1. 函数 function
function 执行特定任务的代码块
可实现代码复用, 提高开发效率
函数和循环区别: 随时调用, 随时执行, 可重复调用
函数可把相同逻辑代码包裹起来, 通过函数调用执行包裹的代码, 有利精简代码方便复用
和变量命名基本一致, 使用小驼峰命名法, 前缀应为动词
函数声明语法
代码语言:javascript复制function 函数名 {
函数体
}
2. 函数调用与使用
函数不调用 自己不执行, 使用()调用函数
曾使用的alert()、parseInt()后面跟小括号的本质都是函数的调用
代码语言:javascript复制// 函数一次声明可多次调用 每一次调用函数 代码都会重新执行一次
say()
say()
循环代码写完即执行,不能方便控制执行位置
函数体是函数的构成部分, 它负责把代码包裹起来, 直到函数调用时函数体代码才会执行
代码语言:javascript复制function say() { // say是函数名
console.log('你好') // 函数体
}
say() // 调用函数
3. 99乘法表封装到函数里, 调用1次
代码语言:javascript复制function say() {
for (let num1 = 1; num1 <= 9; num1 ) {
for (let num2 = 1; num2 <= num1; num2 ) {
document.write(`${num2} x ${num1} = ${num1 * num2}`)
}
document.write(`<br>`)
}
}
say()
4. 封装一个函数, 计算1~100之间的和
代码语言:javascript复制function say() {
let num1 = 0
for (let num2 = 1; num2 <= 100; num2 ) {
num1 = num2
}
document.write(num1)
}
say()
2. 函数传参
若函数完成功能需调用者传入数据, 就需用函数传参
调用函数时, 传几个数据就写几个, 用逗号隔开
提高函数灵活性, 函数分为形参和实参
代码语言:javascript复制function say(num1, num2) { // () 参数列表
document.write(num1 num2)
}
say(1, 100) // () 传递的参数列表 , 隔开
1. 形参和实参
形参: 声明函数时写在函数名右括号叫形参 (形式上参数)
实参: 调用函数时写在函数名右括号叫实参 (实际上参数)
形参可理解为函数内声明变量,实参可理解为变量赋值
开发中需保持形参和实参个数一致
曾使用过alert, parseInt, number本质上都是函数调用传参
2. 函数封装求和
代码语言:javascript复制// 利用逻辑中断 形参不赋值, 则是undefined
function say(num1, num2) {
num1 = num1 || 0
num2 = num2 || 0
document.write(num1 num2)
}
// say(1, 2)
// say()
3. 函数封装求学生总分
代码语言:javascript复制function say(num1) {
let num2 = 0
for (let num3 = 0; num3 < num1.length; num3 ) {
num2 = num2[num3]
}
document.write(num2)
}
say([11, 22, 33])
say([10, 20, 30])
3. 函数返回值
函数缺点: 把计算结果处理写死了, 内部处理了
当调用函数, 函数会返回结果, 这就是有返回值的函数
函数执行后得到结果,结果是调用者要拿到的
很多函数具备返回值(prompt, parseInt)
这些函数是JS底层内置的, 直接可使用, 有的函数, 没有返回值, 根据需求, 来设定返回值
1. return返回数据:
函数需返回数据时, 用return 来返回值
return会立即结束当前函数, 将内部结果交给函数外使用
函数内只能1次return, 并且return后面代码不会被执行, 所以return后面数据不要换行写
函数可以没有return, 这种情况函数默认返回值为undefined
代码语言:javascript复制function say() {
// return 10 相当于 say() = 10
return 10
}
say()
document.write(say())
求任意数组中最大值 并返回最大值
代码语言:javascript复制function say(num1) {
let num2 = num1[0]
for (let num3 = 0; num3 < num1.length; num3 ) {
if (num2 < num1[num3]) {
num2 = num1[num3]
}
}
return num2
}
let re = say([11, 22, 33])
document.write(re)
求任意2个数的最大值 并返回
代码语言:javascript复制function say(num1, num2) {
if (num11 > num2) {
return num1
} else {
return num2
}
}
document.write(say(11, 22))
4. 作用域
作用域的使用提高逻辑局部性, 增强程序可靠性,减少名字冲突
代码中用到的名字并不总有效可用, 而限定名字可用性代码范围叫作用域
全局作用域: 函数外部或整个Script 有效
局部作用域: 函数内部有效, 也叫函数作用域
块级作用域: { }内有效, if和for里的{ } 等…
1. 变量作用域
全局变量: 函数外部let的变量–任何区域都可访问修改
局部变量: 函数内部let的变量–局部变量只能在当前函数内部访问修改
块级变量: {}内部let变量–只能在块作用域访问, 不能跨块、跨函数访问
2. 变量作用域两个坑, 特殊情况
函数内部或块作用域内部, 变量没声明直接赋值, 也当全局变量看, 不推荐
函数内部形参可看做局部变量
5. 作用域链
作用域链:采取就近原则方式来查找变量最终值
只要是代码, 至少有一个作用域
函数中还有函数, 那这个作用域又可诞生一个作用域
根据内部函数可访问外部函数变量机制, 用链式查找决定数据能被内部函数访问叫 作用域链
下面最终结果是几?
代码语言:javascript复制function fn() {
let num1 = 123
function f2() {
console.log(num1)
}
f2()
}
let num1 = 456
fn()
下面最终结果是几?
代码语言:javascript复制let a = 1
function fn1() {
let a = 1
let b = '22'
fn2()
function fn2() {
let a = 2
fn3()
function fn3() {
let a = 3
console.log(a) //a的值 ?
console.log(b) //b的值 ?
}
}
}
fn1()
6. 匿名函数
将函数赋值给变量, 并通过变量名调用叫函数表达式
匿名函数形参和实参使用跟具名函数一样
函数分为: 具名函数, 匿名函数
代码语言:javascript复制let num = function () {
document.write(1)
}
num()
7. 立即执行函数
避免全局变量之间的污染
无需调用, 立即执行, 本质已调用了
多个立即执行函数要用 ; 隔开,不然报错
代码语言:javascript复制// 第一种写法
(function () {
document.write(1)
})()
// 第二种写法
(function () {
document.write(2)
}())
用户输入时间后 转换时间
代码语言:javascript复制let num1 = prompt('请输入总秒数')
function fn(num1) {
let h = parseInt(num1 / 60 / 60 % 24)
let m = parseInt(num1 / 60 % 60)
let s = parseInt(num1 % 60)
h = h < 10 ? '0' h : h
m = m < 10 ? '0' m : m
s = s < 10 ? '0' s : s
return `您输入了${num1}秒,计算后的时间是${h}小时${m}分${s}秒`
}
let re = fn(num1)
document.write(re)