05-javascript基础----js作用域

    科技2022-07-11  79

    一、作用域

    1. 概念 & 作用

    作用域,就是一个代码块所在的区域,它是静态的,在编写代码时就已经确定了

    不同于执行上下文,(执行上下文是动态的,执行创建)

    举例:

    执行上下文时 建房子 时的 打地基

    作用域 是 建房子 时的 区域

    作用:用来决定代码执行的范围,变量所属的范围

    2. 作用域和执行上下文区别

    作用域执行上下文创建时刻函数定义function a() {}函数调用a()性质静态的,函数定义了,就不会变化动态的存在时间不会变化调用时创建,调用结束释放

    联系:

    上下文环境(对象) 是从属于所在的 作用域全局上下文环境 ==> 全局作用域函数上下文 ==> 对应的函数作用域

    二、作用域链

    1. 概念

    作用域链:

    作用域链 ,是一个数组结构该结构保存的是 一个个的变量对象

    作用域 是人们虚拟出来的,实际上,作用域根本不存在

    但是,作用域链是真实存在的

    作用:有句话说:找属性去找原型链,找变量去找作用域链

    流程:

    先在自身的作用域的变量对象找没有,沿着作用域链,去上一个作用域的变量对象找

    2. 例子解释

    看以下代码,我通过断点的方式,来解释这个概念

    /* 断点一 */ var a = 2; function fn1() { /* 断点二 */ var b = 3; function fn2() { /* 断点三 */ var c = 4; console.log(c) // 4 console.log(b) // 3 console.log(a) // 2 console.log(d) // 报错 } fn2() } fn1()

    首先,通过 debug调试,将代码执行带断点一的地方停下

    那么:

    首先创建全局作用域 和 全局变量对象globalglobal收集了函数fn1,为他创建局部作用域这时,在函数fn1建立一个作用域链,里面保存一个变量对象global

    然后,执行到断点二的地方停下:

    首先,在fn1的作用域内,创建一个变量对象Local: fn1Local:fn1,收集了函数fn2,为他创建局部作用域这时,在函数fn2建立一个作用域链,将Local:fn1插入到链的头部那么,这时作用域链,就有[ Local:fn1, global ]

    那么,这个由 [[Scopes]]属性存储的变量对象,就是作用域链

    3. 笔试题(附解析)

    /* 输出什么 */ var x = 10; function fn() { console.log(x) } function show(f) { var x = 20 f() } show(fn)

    答案:10

    解析:

    首先,创建全局作用域和变量对象globalglobal收集函数fn、show,创建局部作用域,两个的作用域链都只有一个global对象执行代码,fn, show创建自身的作用域链,[[scopes]] = [global]执行到fn()时,由于要找变量,那么先找自身的作用域的变量对象Local:fnfn自身没有x变量,找作用域链的上一个变量对象globalglobal的x变量为 10输出 10

    4. 练习

    console.log(fn) var fn = function () { console.log(fn) } fn() var obj = { fn2: function () { console.log(fn2) } } obj.fn2()

    答案:

    第一道:undefined、 f() {console.log(fn)}

    第二道: 报错:fn2 is not function

    Processed: 0.020, SQL: 8