首页 /  技术专区  /  JavaScript 宽屏模式 >

JavaScript 闭包、变量提升、函数提升

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.函数提升出现在相同作用域当中





头像
0/200
图片验证码