<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          js 關(guān)于變量提升的兩道“變態(tài)”面試題,你能做對么?

          共 5377字,需瀏覽 11分鐘

           ·

          2021-09-05 22:57

          點擊上方 前端瓶子君,關(guān)注公眾號

          回復算法,加入前端編程面試算法每日一題群

          老版本瀏覽器沒有塊級上下文的概念

          老版本瀏覽器中,放在{}【排除:函數(shù)、對象】中的function在變量提升階段 都是聲明+定義

          新版本瀏覽器中

          1. 如果function出現(xiàn)在除函數(shù)、對象的大括號中,則在變量提升截斷,只聲明不定義了!

          2.如果除了函數(shù)和對象的大括號中,只要出現(xiàn)let/const/function關(guān)鍵詞,都會產(chǎn)生塊級私有上下文【對var無效】

          注意:var是不受塊的影響的

          // 題1
          // EC(G)
          //  變量提升;
           var a;
           fn=0x000;[[scope]:EC(G)]
           console.log(a); //undefined
           var a=12
           function fn(){
               // EC(FN)
               //  作用域鏈:<EC(FN),EC(G)>
               //  形參賦值:--
               //  變量提升: var a;
               console.log(a); //undefind
               var a=13;   
           }
           fn();   
           console.log(a); // 12


          // 題2
          // EC(G)
          //  變量提升;
               var a;
               fn=0x000;[[scope]:EC(G)]
           console.log(a);  //undefined
           var a=12;
           function fn(){
               // EC(FN)
               //  作用域鏈:<EC(FN),EC(G)>
               //  形參賦值:--
               //  變量提升: --
               console.log(a);//->不是自己的私有變量,是EC(G)中的全局變量 12
               a=13;
           }
           fn();
           console.log(a); //->13



          // EC(G)
          //  變量提升;
          //     fn=0x000;[[scope]:EC(G)]
          console.log(a); //->Uncaught ReferenceError: a is not defined
          a=12;
          function fn(){
              console.log(a);
              a=13;   
          }
          fn();
          console.log(a);
          console.log(foo); //->undefined
          {
              console.log(foo);//->foo() {}
              function foo() {}
              foo = 1;//->私有的foo=1
              console.log(foo);//->1
          }
          console.log(foo);//->? foo() {}
          圖片.png
          // EC(G)
          //  變量提升:
          //      function foo;
          //      function foo;
          console.log(foo); //->undefined
          {
              // EC(BLOCK)
              //  作用域鏈<EC(BLOCK,EC(G))>
              //  變量提升:
              //      foo = 0x001;[[scope]:EC(BLOCK)]
              //      foo = 0x002;[[scope]:EC(BLOCK)]
              //      ------
              //      foo=0x002;
          \

              console.log(foo);//函數(shù){2}
              function foo() {1}//把之前對foo的操作映射給EC(G)一份=>全局foo=0x002
              console.log(foo);//函數(shù){2}
              foo = 1//把私有的foo=1
              console.log(foo);//->1
              function foo() {2}//把之前對foo的操作映射給EC(G)一份=>全局foo=1
              console.log(foo); //->1
          }
          console.log(foo);//->1
          圖片.png
          下面看一下三塊代碼的運行結(jié)果,比較一下區(qū)別
          圖片.png

          當代新版本瀏覽器

          • 一方面兼容ES5語法
          • 一方面還要兼容ES6新語法

          機制:如果當前函數(shù)使用了ES6中的形參賦值默認值【不論是否生效】,并且函數(shù)體中有基于let/const/var聲明 的變量【無論變量名稱是否和形參一致(注意let/const是不允許重復聲明的),則函數(shù)在執(zhí)行的時候,除了形成一個私有的上下文,而且還會把函數(shù)體{}當作一個私有的塊級上下文[并且塊級上下文的上級上下文是私有的那個上下文]

          如果函數(shù)體中聲明的變量和形參變量一直,最開始的時候,會把形參變量的值,同步給私有變量一份

          // 符合條件

          // 符合條件

          function fn(x,y=10){
              var m =20;
          }
          fn(1,2)

          盡可能不要使用形參賦值默認值

          var x = 1;
          function func(x,y=function anonymous1(){x =2}){
              var x = 3;
              var y = function anonymous1(){x = 4}
              console.log(x); 
          }
          func(5);
          console.log(x); 


          // 分析

          var x = 1;
          function func(x,y=function anonymous1(){x =2}){
              // EC(FUNC)
              //  作用域鏈<EC(FUNC),EC(G)>
              //  初始化this:window
              //  形參賦值:
              //      x=5;
              //      y=0x001;[[scope]:EC(FUNC)]
              // EC(BLOCK)
              //  作用域鏈<EC(BLOCK),EC(FUNC)>
              //  變量提升:
              //      var x; ->copy 5 ->3 ->4
              //      var y; ->copy 0x001 ->0x002 [[scope]:EC(BLOCK)]
              var x = 3;
              var y = function anonymous1(){x = 4}
              console.log(x);  // =>4
          }
          func(5);
          console.log(x); //=>1
          圖片.png

          前端路漫漫其修遠兮,吾將上下而求索,一起加油,學習前端吧!

          轉(zhuǎn)自:貍不開

          https://juejin.cn/post/6994620925501177863

          最后

          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認真的解答喲!
          回復「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對你有幫助,在看」是最大的支持
           》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持
          瀏覽 32
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线一区二区三区四区五区 | 九九九在线免费视频 | 蜜桃四季春秘 一区二区三区 | 四虎AV极速 | 一级片精品 |