js作用域

目录

1.作用域(Scope)定义

2.变量的作用域类型

3.作用域链

4.执行期上下文

5.查找变量

6.例1

7.例2

8.闭包的引入


1.作用域(Scope)定义

  [[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。即作用域决定了代码区块中变量和其他资源的可见性。

 

2.变量的作用域类型

  1.全局作用域:全局作用域贯穿整个javascript文档,在所有函数声明或者大括号之外定义的变量,都在全局作用域里。一旦你声明了一个全局变量,那么你在任何地方都可以使用它,包括函数内部。

  2.局部作用域:局部作用域一般只在固定的代码片段内可访问到,而其外部是无法访问的,它分为函数作用域和块级作用域

    a:函数作用域: 当你在函数里定义一个变量时,它在函数内任何地方都可以使用。在函数之外,你就无法访问它了。

    b:块级作用域:你在使用大括号时,声明了一个const或者let的变量时,你就只能在大括号内部使用这一变量。

 

3.作用域链

  作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。

 

4.执行期上下文

  当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,执行上下文被销毁。(即AO、GO,不了解的可参考预预编译文章)

 

5.查找变量

  在函数中查找变量,从其作用域链的顶端依次向下查找,从Scope chain 的0位依次查到最后一位。

 

6.例1

function a() {
    function b() {
        var bb = 234
    }
    var aa = 123;
    b();
}
var glob = 100;
a();

 1.a()定义时,其Scope里存放GO

2.a()执行时,形成作用域链,Scope chain[0] 存放AO, Scope chain[1] 存放GO

   

3: b()定义,因为它是a()内部的函数,因此其执行期上下文与a()执行时是一样的;

  

4:b()执行时,产生自己的AO,在作用域链中将a()的AO与GO储存位置下移,第0位存自己的AO

  

 注意:b()  Scope chain 储存的a() 的AO与a()中的AO一样,只是将其引用挂到里面,即通过b()中可以改变a()中变量的值

 

下面这个例子输出 a 为0;

function a() {   
    function b() {
        var bb = 234;   
        aa = 0; 
    }  
    var aa = 123;
    console.log(a);  
}
var glob = 100;
a();

 

7.例2

先看代码:

function a(){
    var aa = 123;
    function b(){
        var bb = 456;
        function c(){
            var cc = 789;
        }
        c();
    }
    b();
}
a();

这里的调用生成AO,GO顺序为:

        a defined(定义)a.[[scope]]  0:GO
        a doing(执行)  a.[[scope]]  0:AO(a) //a的AO
                                     1:GO

        b defined(定义)b.[[scope]]  0:AO(a)
                                     1:GO 
        b doing(执行)  b.[[scope]]  0:AO(b)
                                     1:AO(a)
                                     2:GO

        c defined(定义)c.[[scope]]  0:AO(b)
                                     1:AO(a)
                                     2:GO 
        c doing(执行)  c.[[scope]]  0:AO(c)
                                     1:AO(b)
                                     2:AO(a)
                                     3:GO

 

8.闭包的引入

看下面这个例子:

function a(){
    function b(){
        var bbb = 234;
        console.log(aaa);
    }
    var aaa = 123;
    return b;
}
var glob = 100;
var demo = a();
demo();

打印是123;

这里 demo = a();当 a() 执行完,一般来说会销毁创建 a 的 AO对象,但是 a() 返回的是 b(),所以没法销毁 a 的 AO对象,因为 b()的作用域链还链着 a 的 AO 对象。

所以执行 console.log(aaa) 的时候,先访问 b 的AO对象,没有 aaa,所以再访问 a 的AO对象,打印123;

 

这个过程称为 闭包

但凡内部的函数被保存到了外部,一定产生闭包

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript 作用指的是变量、函数和对象可以被访问的范围。在 JavaScript 中,作用分为全局作用和局部作用两种。 全局作用指的是在函数外定义的变量和函数,它们可以被整个程序访问。在浏览器中,全局作用指的是 window 对象。 局部作用指的是在函数内部定义的变量和函数,它们只能在函数内部被访问。在 JavaScript 中,每当一个函数被调用时,都会创建一个新的局部作用。 JavaScript 使用词法作用(也称为静态作用)规则来决定变量的作用。这意味着函数的作用是在函数定义时确定的,而不是在函数调用时确定的。因此,在函数内部定义的变量可以在函数外部访问,但函数外部定义的变量不能在函数内部访问。 例如,下面的代码演示了 JavaScript 中的作用: ``` var x = 10; // 全局变量 function foo() { var y = 20; // 局部变量 console.log(x); // 可以访问全局变量 x console.log(y); // 可以访问局部变量 y } foo(); console.log(x); // 可以访问全局变量 x console.log(y); // 不能访问局部变量 y ``` 在上面的例子中,变量 x 是在全局作用中定义的,可以在函数内部和外部访问。变量 y 是在函数内部定义的,只能在函数内部访问。函数 `foo()` 调用后,可以在函数内部访问变量 x 和 y。函数调用结束后,只能在全局作用中访问变量 x,无法访问变量 y。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值