作用域與變量提升的面試題方法總結


前言:下面的方法能快速的解面試題,主要針對 =>作用域與變量提升的面試題<= 。並且沒有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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM