【JS基础】1.函数、匿名函数、回调函数、IIFE(立即执行函数)
1. 认识函数
- 函数到底是什么?
- 函数其实就是某段代码的封装,这段代码帮助我们完成某一下功能
- JS引擎中有一些已经提供的函数
- 我们也可以编写属于自己的函数
- 函数使用的步骤
- 声明函数:封装成独立的功能快
- 调用函数:享受封装的成果
2. 声明函数和调用函数
- 使用function关键字
function foo() {
console.log('这是函数声明')
}
- 函数的返回值
- 使用return来返回结果
- 如果函数没有返回语句,会有默认的返回值undefined
- 如果有return语句,但没有返回任何东西,返回值为undefined
- return语句后面的代码不会执行
- arguments参数
- 默认情况下,arguments对象是所有(非箭头)函数中可用的局部变量
- arguments是一个object类型(array-like)伪数组
function bar() {
console.log(arguments)
// [Arguments] { '0': 1, '1': 2, '2': '测试', '3': { name: '张三' } }
}
bar(1, 2, '测试', { name: '张三' })
3. 函数表达式
- 函数表达式的写法
// 函数表达式的写法
var baz = function () {
console.log('这是用函数表达式创建的函数')
}
-
在JS中函数只是一种特殊的值
-
无论函数是怎么创建的,都是一种特殊的值
-
函数表达式和函数声明的区别
- 函数表达式是在代码到达执行的时候创建
- 函数声明在被定义之前就可以使用
4. JavaScript头等函数
- 头等函数,指函数可以作为函数的参数、返回值、赋值给变量、或者存储在数据结构中
- 通常对头等公民的变成方式,称之为函数式变成
// 定义一个函数
function foo() {
console.log('这是函数foo内部')
function fooSon() {
console.log('这是foo的子函数')
}
return fooSon
}
var bar = function (fn) {
console.log(`这是函数bar`)
return fn()
}
// 函数可以赋值给变量
var baz = foo
// 将函数baz已参数的形式传递给bar
bar(baz)
// 这是函数bar
// 这是函数foo内部
// 调用foo函数
console.log('调用foo')
var returnFun = foo()
returnFun()
// 函数可以存储在数据结构中
var obj = {
name: '张三',
age: 18,
goBack: function (params) {
console.log('我能返回')
}
}
5. 回调函数
- 我们可以将一个函数传递给函数
function foo(type, callback) {
console.log(`这是传递的参数${type}`)
setTimeout(function () {
console.log('foo函数处理type中')
type++
callback(type)
}, 2000)
}
// 显然 foo是一个异步函数,如果我们需要获取最后的type值
// 获取foo处理过的type
function getFooType(type) {
console.log(`获取到了type${type}`)
}
foo(66, getFooType)
// 这是传递的参数66
// foo函数处理type中
// 获取到了type67
- 当然,我们也可以改造成匿名函数更方便使用
function foo(type, callback) {
console.log(`这是传递的参数${type}`)
setTimeout(function () {
console.log('foo函数处理type中')
type++
callback(type)
}, 2000)
}
// 显然 foo是一个异步函数,如果我们需要获取最后的type值
foo(66, function (res) {
console.log(`获取的返回值${res}`)
})
// 这是传递的参数66
// foo函数处理type中
// 获取的返回值67
6 立即执行函数
- 立即执行函数IIFE立即调用函数表达式
- 立即执行函数会创建一个独立的上下文,避免外界访问和修改内部的变量
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
var btns = document.querySelectorAll('button')
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function () {
console.log(`点击了第${i}个button`)
})
}
</script>
显然,在上面的代码中,由于使用var来声明的i,每次点击后得到的i都是4,我们利用立即执行函数改造一下
var btns = document.querySelectorAll('button')
for (var i = 0; i < btns.length; i++) {
;(function (i) {
btns[i].addEventListener('click', function () {
console.log(`点击了第${i + 1}个button`)
})
})(i)
}
立即执行函数,可以有入参,返回值
- 立即执行函数的其他写法
// 常规写法
var result = (function (text) {
var result = {
name: '张三',
age: 18,
action: foo
}
function foo() {
console.log(`匿名函数里面的函数`)
}
console.log(`这是定义的匿名函数`)
console.log(`接收到的参数${text}`)
return result
})('这是形参')
result.action()
// 表达式写法 + -都是表达式,函数也是一个特殊的值
+function foo(){}()