JavaScript作用域与作用域链

先来聊聊变量提升与函数提升

1.变量提升
通过var定义(声明)的变量,在定义语句之前就可以访问到
值是:undefined

console.log(b)
var b = 3
// undefined

2.函数声明提升
通过function声明的函数,在之前就可以直接调用*值:函数定义(对象)

fn()
function fn() {
     
console.log('fn')
}
// fn

作用域

理解:
就像是一块儿地盘,一个代码所在的区域;
它是静态的(相对上下文),在编写代码的时候就确定了;
分类:
全局作用域
函数作用域
块级作用域(es6)
作用:
隔离变量(不同作用域下的同名变量不会有冲突)
看图说话
JavaScript作用域与作用域链_第1张图片

作用域与执行上下文

区别1:
全局作用域之外,每个函数都会创建自己的作用域,作用域是在函数定义的时候就已经确定了,而不是在函数调用的时候;
全局执行上下文环境是在全局作用域确定之后,js代码马上执行之前创建;
函数执行上下文是在调用函数时创建,函数调用结束时就会自动释放;
区别2:
作用域是静态的,执行上下文是动态的;
联系:
上下文环境(对象)是从属于所在的作用域;
全局上下文环境==>全局作用域;
函数上下文环境==>对应的函数作用域;
JavaScript作用域与作用域链_第2张图片

作用域链

理解:
多个上下级关系的作用域形成的链,它的方向是从内到外,从下到上;
查找变量就是沿着作用域链来查找的
JavaScript作用域与作用域链_第3张图片

闭包

如何产生闭包:
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包。
闭包是什么?
理解一:闭包是嵌套的内部函数(大部分人)
理解二:包含被引用变量(函数)的对象(少数人)
注意:闭包存在于嵌套的内部函数中
产生闭包的条件:
函数嵌套;
内部函数引用了外部函数的数据;

常见的闭包

  1. 将函数作为另一个函数的返回值
function fn1() {
     
            var a = 2
            function fn2() {
     
                a++
                console.log(a)
            }
            return fn2
        }
        var f = fn1()
        f()
        f()
  1. 将函数作为实参传递给另一个函数调用
function showDelay(msg,time) {
     
            setTimeout(function (){
     
                alert(msg)
            }, time);
        }
        showDelay('666',2000)

闭包的作用

1.使用函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
2.让函数外部可以操作(读写)到函数内部的数据(变量/函数)
问题:
1。函数执行完后,函数内部声明的局部变量是否还存在?
一般不存在,存在于闭包中的变量才可能存在。
2.在函数外部能直接访问函数内部的局部变量吗?
不能,但是我们可以通过闭包来让外部操作它

闭包的生命周期

1.产生:在嵌套内部函数定义执行完时就产生了(不是在调用)

function fn1() {
     
// 此时闭包已经产生
            var a = 2
            function fn2() {
     
                a++
                console.log(a)
            }
            return fn2
        }
        var f = fn1()
        f()
        f()

2…死亡:在嵌套的内部函数成为垃圾对象时

function fn1() {
     
// 此时闭包已经产生
            var a = 2
            function fn2() {
     
                a++
                console.log(a)
            }
            return fn2
        }
        var f = fn1()
        f()
        f()
        f = null // 闭包死亡

闭包的应用

定义JS模块
具有特定功能的js文件
将所有的数据和功能都封装在一个函数内部(私有的)只向外暴露一个包信n个方法的对象或函数
模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

闭包的缺点

1.缺点
函数执行完后,函数内的局部变量没有释放,占用内存时间会变长容易造成内存泄露
2.解决
*能不用闭包就不用
*及时释放

你可能感兴趣的:(javascript,前端)