• 作用域与变量提升的面试题方法总结


    前言:下面的方法能快速的解面试题,主要针对 =>作用域与变量提升的面试题<= 。并且没有this改变指向的情况

              (有错或者不足的地方,随时修改补充)

    函数的两种形似:1.函数申明(function xx(){ })。2.函数表达式(let xx = function(){ })。

    变量提升(预解析):浏览器刚打开就会预先把带var的函数申明(function xx(){ })进行变量提升,var xx =undefined | xx=function xx(){ }
    作用域:全局作用域:window。  局部作用域:函数体内。  ES6中还有块的概念,块:是个花括号 { } =>在函数申明被花括号包着的括号上方,打印函数是undefined
    重名:如果var 了一个或多个变量,和声明一个或多个函数,重名了。此时可以看做(变量提升的时候,后面的覆盖了前面的,函数申明 覆盖了 var。)

    /*********************上面是知识基础,是铺垫。*************下面是总结的一套方法**************************/
    1.没有参数的时候:看有没有var,或者函数申明(也就是说如果有变量提升,在函数体内就变成私有变量了,函数体内修改了不会影响父级。)
    有,子集是undefined,也不会找父级,下面修改了(简单和复合类型)都不会影响父级。
    没有,子集找不到,会找到父级,下面修改了(简单和复合类型)都会影响父级。


    2.有参数的时候:(有传参,在函数体内就变成私有变量了,函数体内修改了 不会影响父级。除非用的同一个空间地址,也就是复合函数)
    子集找不到,或者是undefined,(有没有var,或者函数申明)都会找参数,简单类型修改了不会影响父级,复合类型修改了会影响父级,除非重新赋址了。

    例子1:

     1     /*全局作用域
     2     1.变量提升:先找var 和函数申明
     3      var a = undefined
     4      fn = function fn(){...}
     5     2.从上而下逐行解读代码:只看 = 号后面的
     6      */
     7     console.log(fn);  //fn = function fn(){...}
     8     var a = 5;
     9     console.log(a);//5
    10 
    11     function fn() {
    12         /*局部作用域
    13         1.变量提升:先找var 和函数申明
    14          var a = undefined
    15          var fn = undefined
    16          fn = function fn(){alert(1);}
    17          (重名了,函数 覆盖了 var)
    18         2.从上而下逐行解读代码:只看 = 号后面的
    19          */
    20         fn = 30;
    21         console.log(fn); //30
    22         var fn = function () {
    23             alert(1);
    24         };
    25         a = 50;
    26         console.log(fn, a); //function(){alert(1);},50
    27         function fn() {
    28             alert(5);
    29         }
    30         console.log(fn); //function(){alert(1);}  (解读的时候看 = 等号,有等号赋值后就看等号后面的)
    31         var a = fn = 70;//相当于var了一个a = 70   和赋值了一个  fn = 70
    32         console.log(a, fn); //70,70
    33         //window.fn = 70;
    34         window.a = 80
    35     }
    36     fn();
    37     console.log(a, fn); //80,整个大的代码块 (没有参数,看函数体内有没有var fn  和fn的函数声明。有,函数体内形参私有作用域,里边的fn改变了,不会影响外面的fn,除非是挂在window下,比如window.a = 80)

    例子2:

    1     function b(x, y, a) {
    2         console.log(a);//3  先找本身有没有,本身找不到,会找参数有没有,再找父级,找到全局。为止,全没有就报错。
    3         arguments[2] = 10;//相当于 a = 10
    4         console.log(a);//10  本身找的到,,就不会往外找
    5     }
    6     a = b(1, 2, 3);
    7     console.log(a);//a,拿到时是函数b的默认返回值,(undefined)

    结语:想把这种类型的题目吃透,一定要多练,光说不练假把式。复杂一点,还要学习闭包的机制this指向的问题,运算符优先级的问题,下面再给个例子

    例子3:(考虑 运算优先级的面试题)

     1      var a=9;
     2      function fn(){
     3          a=0;
     4          return function(b){
     5              return b + (a++);//b先加上a,得出结果。a再自增
     6          }
     7      }
     8     var f=fn();//a = 0
     9     console.log(f(5)); //5   a = 1
    10     console.log(fn()(5)); //a=0   5   a = 1
    11     console.log(f(5)); //6  a=2
    12     console.log(a); //2

     例子4:(闭包 和 this指向 的综合面试题)

     1     var num = 10;
     2     var obj = {num: 20};
     3     /*
     4         obj = {
     5             num:20,
     6             fn:function (n) {
     7                 this.num += n;  
     8                 num++;
     9                 console.log(num);
    10             }
    11         }
    12         fn = function (n) {
    13             this.num += n;
    14             num++;
    15             console.log(num);
    16         }
    17     */
    18     obj.fn = (function (num) { //num=20
    19         //window.num = 60
    20         this.num = num * 3;
    21         num++;
    22         //num=21
    23         return function (n) {
    24             this.num += n;
    25             num++;
    26             console.log(num); //22  23
    27         }
    28     })(obj.num); //匿名函数自执行的this就是window
    29     var fn = obj.fn;
    30     fn(5);//60 += 5  65 window.num = 65    num=22
    31     obj.fn(10); //20 += 10    obj.num = 30
    32     console.log(num, obj.num); //65  30
  • 相关阅读:
    linux:centOs7换源阿里云
    nginx:负载均衡实战(一)
    linux-安装jdk以及tomcat
    nginx:在linux上进行nginx的安装
    开源 免费 java CMS
    使用PHP获取汉字的拼音(全部与首字母)
    php版获取重定向后地址的代码分享
    php获取数组中重复数据的两种方法
    php删除html标签的三种解决方法
    php curl 伪造IP来源的代码分享
  • 原文地址:https://www.cnblogs.com/MrZhujl/p/9853562.html
Copyright © 2020-2023  润新知