宽屏
1. 闭包
概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域
简单理解: 闭包 = 内层函数 + 外层函数的变量
先看个简单的代码:
function outer() {
const a = 1
function f() {
console.log(a)
}
f()
}
outer()闭包的基本格式
function outer() {
let i = 1
function fn() {
console.log(i)
}
return fn
}
const fun = outer()
fun() // 1
// 外层函数使用内部函数的变量简约写法:
// 简约写法
function outer() {
let i = 1
return function() {
console.log(i)
}
}
const fun = outer()
fun() // 调用fun 1
// 外层函数使用内部函数的变量闭包应用:实现数据的私有
比如,我们要做个统计函数调用次数,函数调用一次,就++
let count = 1
function fn() {
count++
console.log(`函数被调用${count}次~`)
}
fn() // 2
fn() // 3但是,这个count 是个全局变量,很容易被修改
function fn(){
let count = 1
function fun(){
count++
console.log(`~函数被调用${count}次~`)
}
return fun
}
const result = fn()
result() // 2
result() // 3这样实现了数据私有,无法直接修改count
2. 变量提升
变量提升是 JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问(仅存在于 var 声明变量)
<script> // 访问变量 str console.log(str + 'world!') // 声明变量 str var str = 'hello' </script>
注意:
1.变量在未声明即被访问时会报语法错误
2.变量在var声明之前即被访问,变量的值为 undefined
3.let/const 声明的变量不存在变量提升
4.变量提升出现在相同作用域当中
5.实际开发中推荐先声明再访问变量
变量提升是什么流程?
先把 var 变量提升到当前作用域于最前面
只提升变量声明,不提升变量赋值
然后依次执行代码
说明:
JS初学者经常花很多时间才能习惯变量提升,还经常出现一些意想不到的bug,正因为如此,ES6 引入了块级作用域用 let 或者 const 声明变量,让代码写法更加规范和人性化。
3. 函数提升
函数提升与变量提升比较类似,是指函数在声明之前即可被调用。
// 调用函数
foo()
// 声明函数
function foo() {
console.log('声明之前即被调用...')
}// 不存在提升现象
bar() // 错误 Uncaught TypeError: bar is not a function at xxx.html:23:1
var bar = function() {
console.log('函数表达式不存在提升现象...')
}总结:
1.函数提升能够使函数的声明调用更灵活
2.函数表达式不存在提升的现象
3.函数提升出现在相同作用域当中