zoukankan      html  css  js  c++  java
  • JavaScript作用域(链)学习笔记

         作用域是javascript老生常谈的问题,在面试题中也经常出现。此文记录本人对js作用域的理解。从以下三个方面深入探讨js作用域和js作用域链。

      1、什么是作用域?

      2、什么是作用域链?

      3、常见面试题。

      

      一、什么是作用域?

        熟悉编程的人都接触过作用域,比如全局变量和局部变量之分。作用域是变量和函数可以访问的范围,即作用域控制着变量和函数的可见性和生命周期。

    var name = "Aralic";
    function person () {
        //局部变量  
        var age = "22";
        
        console.log(country) // "china"
        console.log(name);  //  'Aralic'
        console.log(age);   //   22
    }
    
    person();    

    在这段代码中,函数person就创建一个作用域,作用域里面定义了一个变量age,在函数person外面是无法访问这个变量的。但是在函数person内部是可以访问到变量name,

    因为name是函数person外面定义的,相对函数person是全局变量。

      二、什么是作用域链?

        其实上面的例子已经出现了作用域链了。本来想画图解释的,可惜画图功底实在太差了。还是上代码吧。

    var country = "china";
    function china () {
      var name = "Aralic";
      function person () {
        //局部变量  
        var age = "22";
        
        console.log(country) // "china"
        console.log(name);  //  'Aralic'
        console.log(age);   //   22
      }
    
      person();    
    }
    
    china ();

    在函数person中,访问country的过程:先从函数内部找,发现没有country这个变量,那玩外层函数china找,结果还是没有找到,那继续往外找,结果找到了,不容易啊,嘿嘿,那这就是作用域链,一环扣一环,很厉害,有木有!

    扩展:看到这里,有小伙伴就要问了,假如在函数person里面也定义一个变量country=“American”,那结果会是怎么样?会不会变量冲突?

    大声告诉你,不会冲突,结果就是直接打印出来American。不会向外层查找了。这样就形成了一条完整的作用域链,如果找到浏览器顶层window还没有访问到目标变量和函数,

    那直接返回脚本错误!

    性能相关小技巧: 如果函数嵌套比较深,那么我们在最里面函数中用原生方法比如,document.getElementById(id); 那么这个document我们是不是需要一层一层向外查找,

    那考虑到性能问题,我们是不是可以直接在函数里面把document赋值给一个变量,那每次只要访问这个变量就终止查找了!

         三、常见面试题:

      我们已经学习了作用域和作用域链的知识,那么下面来看几个面试题。

    第一题:

    var  name = "Aralic";
    
    function person () {
       console.log(name);
       var name = "Aralic";
       } person();

    博主第一次见到这个题目的时候,以为答案是Aralic,有没有人和我想的一样的?

    在函数执行前,javascript存在预编译过程。

    当调用函数person的时候会先预编译,把变量和函数声明提升,转成 

    function person () {
    
      var name; //不赋初始值
    
      console.log(name);// 输入undefined
    
      var name = "Aralic";
    
      console.log(name) // 输出Aralic
    
    }
     
    person ();

    第二题:

      var name = 'Aralic';
      function person() {
            console.log(name);
       }
     
       function test() {
           var name = 'tom';
           person();
       }
     
       test();

    这个题目看起来有点绕,先执行test函数,然后在test函数里面调用person函数,执行person函数,打印name变量,那到底name变量是从test函数里面找,还是直接访问最外面的name全局变量。这个题目和作用域链有关,说起来,person和test函数地位是相同的,所以是直接从最外面找name。

     更多相关问题:请阅读《单页web应用》第二章节,讲的比较详细。

  • 相关阅读:
    [LeetCode][SQL]Rising Temperature
    google API的.NET库
    Google Reader的另一个开源的替代品Go Read
    C#中反射接受的字符串需要满足的Backus-Naur Form语法
    Windows的应用管理工具 PortableApps,Chocolatey和Ninite
    如何定制Windows系统右键菜单
    另一个有趣的Captcha 网站
    .gitignore模板
    遇到sql server的问题时如何排查
    如何传播你的代码
  • 原文地址:https://www.cnblogs.com/Aralic/p/4463269.html
Copyright © 2011-2022 走看看