zoukankan      html  css  js  c++  java
  • 浅谈javascript中的作用域

    首先说明一下:Js中的作用域不同于其他语言的作用域,要特别注意。

    JS中作用域的概念:

      表示变量或函数起作用的区域,指代了它们在什么样的上下文中执行,亦即上下文执行环境。Javascript的作用域只有两种:全局作用域和本地作用域,本地作用域是按照函数来区分的。

    首先来看几道题目:

    1.

    复制代码
    if(true){
    var aa= "bb";
    }
    console.log(aa); //bb

    for(var i = 0; i < 100; i++){
    //do
    }
    console.log(i); //100
    复制代码

    2.

    复制代码
    var bb = '11111';
    function aa() {
    alert(bb);//undefine
    var bb = 'test';
    alert(bb);//test
       var cc = "test1";
    alert(age);//语法错误
    }
    aa();
    alert(bb);//11111 
    alert(cc);//语法报错

    复制代码

    3.

    复制代码
    var test = '1111111';
    function aa() {
    alert(test);
    }

    function bb() {
    var test = '22222222';
    aa();
    }

    bb();//alert(1111111);
    复制代码

    4.

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

    5.

    复制代码
    function aa(){
    var bb = "test";
    cc = "测试";
    alert(bb);
    }
    aa();
    alert(cc);//测试
    alert(bb);//语法报错
    复制代码

    上面这5道题目全部概括了js中作用域的问题

    可以总结出这么几个观点

    一、无块级作用域

    从第一题中可以看出来,在{}中执行后,变量并没有被销毁,还是保存在内存中的,因此我们可以访问到的。

    二、JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.

    这里提到函数的作用域链这个概念,在ECMA262中,是这样的

    1. 任何执行上下文时刻的作用域, 都是由作用域链(scope chain)来实现.
    2. 在一个函数被定义的时候, 会将它定义时候的scope chain链接到这个函数对象的[[scope]]属性.
    3. 在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中.

    所以题目3 结果是alert(1111111);

    三、JS会提前处理function定义式 和var关键字

      如题目4 开始alert(bb); //undefine ,alert(age)//语法报错,这两个有什么区别呢,原因就是后面有var bb =“test”,在初始化的时候提前处理了var 这个关键字,只是这个开始未赋值

    将代码修改成这样的,可以看出来

    复制代码
    var dd = '11111';
    function aa() {
    alert(bb);//undefine
       var bb = 'test';
    alert(bb);//test
       var cc = "test1";
    alert(age);//语法错误
    }
    aa();
    alert(dd);//11111
    alert(cc);//语法报错
    复制代码

    此处alert(bb)没有报语法错误,alert(age)报语法错误。

    但是请注意:

    复制代码
    <script>
    alert(typeof aa); //结果:undefined
    </script>
    <script>
    function aa() {
    alert('yupeng');
    }
    </script>
    复制代码

    这说明js预编译是以段为单元的。题目4同理

    四、函数级作用域

      函数里面的定义的变量,在函数执行完后就销毁了,不占有内存区域了。

      所以题目2最后的alert(cc);语法报错,题目5最后到 alert(bb)同理

  • 相关阅读:
    JS两个页面通过URL传值
    新起点 新开始
    Spring Boot 常见标签
    关于Redis缓存数据库
    JPA问题汇总
    Dynamic 报表服务开发
    Dynamic crm自定义页面
    Dynamic 根据用户的角色权限设置相应的按钮显示
    Dynamic 工具类
    Dynamic 点击按钮,弹出一个漂浮页面
  • 原文地址:https://www.cnblogs.com/m2maomao/p/7760522.html
Copyright © 2011-2022 走看看