• JavaScript作用域实战


    ● 首先,我们先创建一个函数,和以前一样,计算一个年龄的

    function calcAge(birthYear) {
      const age = 2037 - birthYear;
      return age;
    }
    
    • 1
    • 2
    • 3
    • 4

    ● 然后我们创建一个全局变量,并调用这个函数

    const firstName = "IT知识一享";
    calcAge(1998);
    
    • 1
    • 2

    ● 因为firstName是一个全局变量,所以在函数中,我们也可以调用这个变量

    function calcAge(birthYear) {
      const age = 2037 - birthYear;
      console.log(firstName);
      return age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    注:这里函数首先会在自己的作用域中找这个变量,如果找不到,会向上从作用域链中寻找这个变量,直到找到为止,如果找不到的话就会报错!

    ● 现在我们在函数内再添加一个函数

    function calcAge(birthYear) {
      const age = 2037 - birthYear;
    
      function printAge() {
        const output = `${age}岁了,出生于${birthYear}`;
        console.log(output);
      }
      printAge();
      return age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    注:printAge函数中调用了age变量,但是再函数作用域中并未找到,所以就通过作用域链再父范围去寻找,最终找到打印出来,但是age变量只能再calcAge整个函数内部使用,外部无法使用这个变量

    function calcAge(birthYear) {
      const age = 2037 - birthYear;
    
      function printAge() {
        const output = `${age}岁了,出生于${birthYear}`;
        console.log(output);
      }
      printAge();
      return age;
    }
    
    const firstName = 'IT知识一享';
    calcAge(1998);
    console.log(age);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    记住,翻译链是单项的,只能内部访问外部,外部无法访问到内部!
    ● 当然,在函数中,我们也可以把firstName加上,因为他是全局变量

     function printAge() {
        const output = `${firstName},你${age}岁了,出生于${birthYear}`;
        console.log(output);
      }
      printAge();
      return age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    ● 现在,我们在printAge中添加if判断

     function printAge() {
        const output = `${firstName},你${age}岁了,出生于${birthYear}`;
        console.log(output);
      }
    
      if(birthYear >= 1981 && birthYear <= 1996) {
        const str = `哇哦,你是千禧一代的人,${firstName}`;
        console.log(str);
      }
    
      printAge();
      return age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    因为firstName是全局变量,所以if条件仍然可以通过作用域链找到这个变量。

    ● 但是str的变量在if之外的区域则无法被访问

    function printAge() {
        const output = `${firstName},你${age}岁了,出生于${birthYear}`;
        console.log(output);
      }
    
      if (birthYear >= 1981 && birthYear <= 1996) {
        const str = `哇哦,你是千禧一代的人,${firstName}`;
        console.log(str);
      }
      console.log(str);
    
      printAge();
      return age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    因为let和const是块作用域,所以上述才能生效
    ● 现在我们使用var创建一个变量

     if (birthYear >= 1981 && birthYear <= 1996) {
        var millenial = true;
        const str = `哇哦,你是千禧一代的人,${firstName}`;
        console.log(str);
      }
      console.log(millenial);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    因为var并不是块级作用域,而是函数作用域,它知识在函数中调用可以,但是全局中或者脱离上一级函数情况下仍然不可以,这是还是要符合作用域链的;
    ● 当然,现在我们在if中创建一个功能函数,仍然是块级区域,无法在外部访问

     if (birthYear >= 1981 && birthYear <= 1996) {
        var millenial = true;
        const str = `哇哦,你是千禧一代的人,${firstName}`;
        console.log(str);
    
        function add(a, b) {
          return a + b;
        }
      }
      console.log(millenial);
      console.log(add(2, 3));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    注:这仅仅是在严格模式下
    在这里插入图片描述

    ● 但是如果我们把严格模式去除的话,则会被正常调用
    在这里插入图片描述

    但是我们使用会用严格模式去编写我们的代码,这样会让代码出现奇奇怪怪的的情况变得很少!
    ● 如果我们在if条件中去声明姓名变量的话,会发生什么情况呢?

     if (birthYear >= 1981 && birthYear <= 1996) {
        var millenial = true;
        const firstName = "mark";
        const str = `哇哦,你是千禧一代的人,${firstName}`;
        console.log(str);
    
        function add(a, b) {
          return a + b;
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    这更加验证了,它会首先在在自己所在的作用域去寻找,如果找到的话,它不会通过作用域链去向父范围查找;除此之外,我们不应该把内部的firstName和外部的看作是一个变量,从本质来讲,它们就是两个变量,只是恰巧名字一样罢了。
    ● 那如果我们在内部讲外部的函数重新赋值,那又是什么情况呢?

    function calcAge(birthYear) {
      const age = 2037 - birthYear;
    
      function printAge() {
        let output = `${firstName},你${age}岁了,出生于${birthYear}`;
        console.log(output);
    
        if (birthYear >= 1981 && birthYear <= 1996) {
          var millenial = true;
          const firstName = 'mark';
          const str = `哇哦,你是千禧一代的人,${firstName}`;
          console.log(str);
    
          function add(a, b) {
            return a + b;
          }
    
          output = 'NEW OUTPUT';
        }
        console.log(millenial);
        //   console.log(add(2, 3));
        console.log(output);
      }
      printAge();
      return a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    ● 但是如下

    const output = 'NEW OUTPUT';
    
    • 1

    在这里插入图片描述

    重新赋值变量和创建变量是不同的!

  • 相关阅读:
    java毕业设计阿博图书馆管理系统mybatis+源码+调试部署+系统+数据库+lw
    tinymce实现导入word功能
    03. Springboot集成Mybatis-flex(一)
    【MySQL | 运维篇】04、MySQL 分库分表之 MyCat 入门与配置
    MySQL之视图、存储过程
    Python控制程控电源
    定档11月2日,YashanDB 2023年度发布会完整议程公布
    平抑风电波动的电-氢混合储能容量优化配置
    leetcode 342. Power of Four(4的次方)
    腾讯云4核8G云服务器租用价格选轻量还是CVM?性能如何?
  • 原文地址:https://blog.csdn.net/weixin_42952508/article/details/134255626