zoukankan      html  css  js  c++  java
  • js基础系列之【作用域】

    声明:形成本文的出发点仅仅是个人总结记录,避免遗忘,并非详实的教程;文中引用了经过个人加工的其它作者的内容,并非原创。学海无涯

    什么是作用域

      作用域就是一套规则,用于确定在何处以及如何查找变量(标识符)的规则

      伪代码帮助理解

    function foo() {
        var a = 'ice';
        console.log(a);
    }
    foo();

      执行函数foo,打印变量a,这个a从哪来呢? 很显然有一句:“var a = 'ice'” 声明了一个变量a,并赋值为‘ice’;

      再来一段不一样的

    var a = 'ice';
    function foo() {
        console.log(a);
    }
    foo();

      按照之前的规则,此时函数foo内部并没有变量a的声明,那a是从哪来的呢?答案是在全局作用域中有“var a = 'ice'”的声明,从这里查找到了a

      通俗得讲,作用域就是查找变量的地方

    有哪些种类作用域

      便于理解但不一定准确得说:作用域按照查找规则来说分为词法作用域(静态作用域)和动态作用域

      词法作用域:定义在词法阶段的作用域;换句话说就是在代码书写完时,作用域就确定了;

      动态作用域:代码执行(函数执行)的时候才确定的作用域;与代码的书写位置无关;

      伪代码来分析一下这两种作用域的不同

    var val = 1;
    function foo() {
        console.log(val);
    }
    
    function bar() {
        var val = 2;
        foo();
    }
    
    bar();

      如果javascript使用的是动态作用域

        执行bar函数时bar函数内部声明了‘val’变量并赋值为2,执行foo函数,打印val变量,在foo内部查找val,如果没有则查找的是位于bar函数内部的val变量,故打印2;

      如果javascript使用的是词法作用域

        声明全局变量val、函数foo、函数bar;函数foo内使用到了变量val,在其内部没有找到则根据书写位置向外层查找到全局作用域中的val;故打印1;

      其实经过我们实际验证,结果是打印1,也就是说javascript使用的是词法作用域

      按照作用域的作用范围分为:全局作用域、函数作用域块级作用域

      同样通过代码展现

    var val = 1; // 全局作用域
    
    function foo() {
        var val = 2; // 函数作用域
    
        if(true) {
            let val = 3; // 块级作用域(es6引入)
        }
    }
    
    // 另外几种形式的块级作用域
    var obj = {a: 'aa', b: 'bb'};
    with(obj) {
        a = 'aaa';
        c = 'ccc';
        console.log(a, c); // 'aaa', 'ccc'
    }
    console.log(a); // Uncaught ReferenceError: a is not defined
    console.log(c); // 'ccc’ with中的c被泄露到了全局变量
    
    
    
    var e = 'default';
    try{
        var temp = 1;
        throw(456);
    } catch(e) {
        var e;
        var x = 123;
        console.log(e); // 456 对于e来说是catch块中的局部变量
        console.log(delete e); // false e不可使用delete移除
        console.log(x); // 123
        e = 789;
        console.log(e); // 789重新赋值e
    }
    console.log(temp); // try并不会重新创建块级作用域
    console.log(e); // ‘default’ catch中对e的重新声明赋值并没有影响全局中的e
    console.log(x); // 123 

    最后一个思考题,回顾作用域

    var zoo = 'global';
    function foo() {
        var zoo = 'local';
        function bar() {
            return zoo;
        }
        return bar();
    }
    foo(); // 执行结果‘local’
    
    var zoo = 'global';
    function foo() {
        var zoo = 'local';
        function bar() {
            return zoo;
        }
        return bar;
    }
    foo()(); // 执行结果‘local’
  • 相关阅读:
    基本类型和包装类对象使用 == 和 equals进行比较的结果?
    ==和equals的区别是什么?
    JDK和JRE有什么区别?
    Java自学指南三、入门视频优先
    Java自学指南二、后端开发全景图与快速入门
    Java自学指南一、找一个开始并能坚持下去的理由
    什么是 happens-before 原则?
    什么是 Java 内存模型?
    Java 中有哪些无锁技术来解决并发问题?如何使用?
    什么是活锁和饥饿?
  • 原文地址:https://www.cnblogs.com/innooo/p/10373491.html
Copyright © 2011-2022 走看看