【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(){}()