文章目录
- 1. 普通函数-无形参
- 2. 普通函数-有形参
- 3. 普通函数-参数默认值
- 4. 普通函数-返回值
- 5. 立即执行函数
- 6. 匿名函数
- 7. 箭头函数
- 8. 函数提升
1. 普通函数-无形参
函数定义时没有指定形参, 调用时仍然可以向其传递参数, 通过默认参数 arguments 获取, arguments 是一个伪数组, 用来获取实参列表
<script>
// 定义函数-无形参
function func() {
// 将 伪数组 arguments 转为真数组
let paramArray = [].slice.call(arguments)
if (paramArray.length > 0) {
console.dir('有参调用, 参数列表 ' + [].slice.call(arguments).toString())
} else {
console.log('无参调用')
}
}
func() // 无参调用
func('a', 'b') // 有参调用
</script>
2. 普通函数-有形参
- 即使函数定义时指定了形参, 调用时仍然可以不传实参
- 实参和形参的个数可以不符, 但是形参的顺序是不能改变的
<script>
// 定义函数-有形参-有返回值
function func(param1, param2) {
if (!param1 && !param2) {
console.log('参数未传')
} else {
console.log('参数1: ' + param1 + ' 参数2: ' + param2)
}
}
func() // 无参调用
func('a', 'b') // 有参调用
func('a') // 形参和实参个数不符
</script>
3. 普通函数-参数默认值
<script>
// 定义函数-有形参-有返回值
function func(param1, param2 = '默认值') {
console.log('参数1: ' + param1 + ' 参数2: ' + param2)
}
func('a', 'b') // 参数1: a 参数2: b
func('a') // 参数1: a 参数2: 默认值
</script>
4. 普通函数-返回值
未显式指定返回值时, 函数默认返回 undefined
<script>
// 显式指定返回值
function result() {
return '返回值'
}
console.log(result()) // 返回值
// 函数默认返回值
function noResult() {
}
console.log(noResult()) // undefined
</script>
5. 立即执行函数
- 程序一运行就会被执行, 不需要调用
- 如果立即执行函数前有其他代码,那么它的前一行代码, 不能省略
;
号
<script>
// 语法 1:( 函数定义 )()
let fn;
(fn = function run() {
console.log('这是立即执行函数')
})()
// fn() 可反复调用
console.log('如果立即执行函数前有其他代码,那么它的前一行代码, 不能省略 ; 号');
// 语法 2:( 函数定义() )
(function run() {
console.log('这是立即执行函数')
}())
</script>
6. 匿名函数
常用场景: 函数表达式、回调函数、立即执行函数等。
<script>
// 场景 1:函数表达式
const caller = function () {
console.log('匿名函数')
}
caller()
// 场景 2:回调函数
function run(callback) {
callback();
}
run(function () {
console.log('匿名函数')
});
// 场景 3:立即执行函数
(function () {
console.log('匿名函数')
})()
</script>
7. 箭头函数
- 箭头函数是匿名函数的语法糖
- 不是所有匿名函数场景都适合用箭头函数替换, 比如箭头函数就没有其他函数的默认参数 arguments
- this 的指向由箭头函数声明的地方决定
匿名函数和箭头函数语法对比
<script>
// 1. 无参的对比
const fn1 = function () {
}
const fn1 = () => {
}
// 2. 单参的对比
const fn2 = function (a) {
}
const fn2 = a => {
} // 单个参数时, 箭头函数的参数列表可以省略小括号 ()
// 3. 多参的对比
const fn3 = function (a, b) { }
const fn3 = (a, b) => {
}
// 4. 函数体只有一行代码的对比
const fn4 = function () {
return '返回值'
}
const fn4 = () => '返回值' // 函数体只有一行代码时, 箭头函数的函数体可以省略大括号 {}
// 函数体只有一行代码并且返回的是对象时, 要在函数体外加上 ({})
const fn4 = () => ({ name: '3s', age: 27 })
// 5. 函数体多行代码对比
const fn5 = function () {
let str = '返回值'
return str
}
const fn5 = () => {
let str = '返回值'
return str
}
</script>
8. 函数提升
- JS 引擎在预解析时, 会把函数声明部分提升至函数调用之前。所以 JS 编写时就算函数先调用后定义, 也可以正常运行
- 函数表达式不会进行函数提升
<script>
// 先调用
func();
// 后定义
function func() {
console.log('函数声明会被提升到函数调用之前')
}
/*
JS 引擎预编译后, 会变成类似这段代码
function func(){
console.log('函数声明会被提升到函数调用之前')
}
func();
*/
</script>