<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        為什么說JavaScript預解釋是一種毫無節操的機制詳析

        來源:懂視網 責編:小采 時間:2020-11-27 22:03:44
        文檔

        為什么說JavaScript預解釋是一種毫無節操的機制詳析

        為什么說JavaScript預解釋是一種毫無節操的機制詳析:前言 JavaScript是一門解釋型的語言 , 想要運行JavaScript代碼需要兩個階段 編譯階段: 編譯階段就是我們常說的JavaScript預解釋(預處理)階段,在這個階段JavaScript解釋器將完成把JavaScript腳本代碼轉換到字節碼 執行階段: 在編譯階段JavaScr
        推薦度:
        導讀為什么說JavaScript預解釋是一種毫無節操的機制詳析:前言 JavaScript是一門解釋型的語言 , 想要運行JavaScript代碼需要兩個階段 編譯階段: 編譯階段就是我們常說的JavaScript預解釋(預處理)階段,在這個階段JavaScript解釋器將完成把JavaScript腳本代碼轉換到字節碼 執行階段: 在編譯階段JavaScr

        前言

        JavaScript是一門解釋型的語言 , 想要運行JavaScript代碼需要兩個階段

      1. 編譯階段: 編譯階段就是我們常說的JavaScript預解釋(預處理)階段,在這個階段JavaScript解釋器將完成把JavaScript腳本代碼轉換到字節碼
      2. 執行階段: 在編譯階段JavaScript解釋器借助執行環境把字節碼生成機械碼,并從上到下按順序執行
      3. 本文就重點介紹預解釋,框架圖如下:

        一、什么是預解釋

        在js中,帶var 和function關鍵字的需要預解釋:

        那什么是預解釋?就是在js代碼執行之前,先申明好帶有var 關鍵字和帶有function關鍵字的變量,在內存里先安排好。

        預解釋:JavaScript代碼執行之前,瀏覽器首先會默認的把所有帶var和function的進行提前的聲明或者定義

        1.理解聲明和定義

        聲明(declare):如var num;=>告訴瀏覽器在全局作用域中有一個num的變量了;如果一個變量只是聲明了但是沒有賦值,默認的值是undefined

        定義(defined):如num=12;=>給我們的變量進行賦值。

        2.對于帶var和function關鍵字的在預解釋的時候操作不一樣的

        var =>在預解釋的時候只是提前的聲明

        function =>在預解釋的時候提前的聲明+定義都完成了

        3.預解釋只發生在當前的作用域下。

        例如:開始只對window下的進行預解釋,只有函數執行的時候才會對函數中的進行預解釋

        二、作用域鏈

        1.如何區分私有變量和全局變量?

        1)在全局作用域下聲明(預解釋的時候)的變量是全局變量

        2)只有函數執行會產生私有的作用域,比如for(){}、if(){}和switch(){}都不會產生私有作用域

        3)在"私有作用域中聲明的變量(var 聲明)"和"函數的形參"都是私有的變量。在私有作用域中,代碼執行的時保遇到了一個變量,首先我們需要確定它是否為私有的變量,如果是私有的變量,那么和外面的沒有在何的關系;如果不是私有的,則往當前作用域的上級作用域進行查找,如果上級作用域也沒有則繼續查找,一直找到window為止,這就是作用域鏈。

        我們舉個例子來區別私有變量和全局變量:

        //=>變量提升:var a;var b;var c;test=AAAFFF111;
        var a=10,b=11,c=12;
        function test(a){
        //=>私有作用域:a=10 var b;
        a=1;//=>私有變量a=1
        var b=2;//=>私有變量b=2
        c=3;//=>全局變量c=3
        }
        test(10);
        console.log(a);//10
        console.log(b);//11
        console.log(c);//3

        判斷是否是私有變量一個標準就是是否是在函數中var聲明的變量和函數的形參都是私有的變量。本道題目在test函數中a是形參和var b定義的變量b都是私有變量。

        2.函數傳參

        這是因為當函數執行的時候,首先會形成一個新的私有的作用域,然后按照如下的步驟執行:

        1)如果有形參,先給形參賦值

        2)進行私有作用域中的預解釋

        3)私有作用域中的代碼從上到下執行

        我們來看一道例題

        var total=0;
        function fn(num1,num2){
        console.log(total);//->undefined 外面修改不了私有的
        var total=num1 +num2;
        console.log(total);//->300
        }
        fn(100,200);
        console.log(total);//->0 私有的也修改不了外面的

        3.JS中內存的分類

        棧內存:用來提供一個供JS代碼執行的環境,即作用域(全局作用域/私有的作用域)

        堆內存:用來存儲引用數據類型的值。對象存儲的是屬性名和屬性值,函數存儲的是代碼字符串。

        三、全局作用域下帶var和不帶var的區別

        我們先來看以下兩個例子:

        //例題1
        console.log(num);//->undefined
        var num=12;
        //例題2
        console.log(num2);//->Uncaught ReferenceError:num2 is not defined 
        num2=12;//不能預解釋

        當你看到var num=12時,可能會認為只是個聲明。但JavaScript實際上會將其看成兩條聲明語句:var num;num=12;第一個定義聲明是在預解釋階段進行的。第二個賦值聲明會被留在原地等待執行階段。num2=12 相當于給window增加了一個叫做num2的屬性名,屬性值是12;而var num=12 首先它相當于給全局作用域增加了一個全局變量num,它也相當于給window增加了一個屬性名num2,屬性值是12。兩者最大區別:帶var的可以進行預解釋,所以在賦值的前面執行不會報錯;不帶var的是不能進行預解釋的,在前面執行會報錯;

        接下來我們舉例說明:

        //例題1
        var total=0;
        function fn(){
        console.log(total);//undefined
        var total=100;
        }
        fn();
        console.log(total);//0
        //例題2
        var total=0;
        function fn(){
        console.log(total);//0
        total=100;
        }
        fn();
        console.log(total);//100

        例題1中帶var變量在私有作用域中可以預解釋,所以第一個console打出來的值為undefined。私有作用域中出現的一個變量不是私有的,則往上級作用域進行查找,上級沒有則繼續向上查找,一直找到window為止,例題2中不帶var變量不是私有的,所以往上級找

        四、預解釋五大毫無節操的表現

        1.預解釋的時候不管你的條件是否成立,都要把帶var的進行提前的聲明。

        請看下面這道例題:

        if(!("num" in window)){
        var num=12;//這句話會被提到大括號之外的全局作用域:var num;->window.num; 
        }
        console.log(num);//undefined

        2.預解釋的時候只預解釋”=”左邊的,右邊的值,不參與預解釋

        請看下面這道例題:

        fn();//報錯
        var fn=function (){ //window下的預解釋:var fn;
        console.log("ok");
        };

        3.自執行函數:定義和執行一起完成了。

        自執行函數定義的那個function在全局作用域下不進行預解釋,當代碼執行到這個位置的時候定義和執行一起完成了。常見有以下幾種形式:

        (function(num){})(10);
        ~function(num){}(10);
        +function(num){}(10);
        -function(num){}(10);
        !function(num){}(10);

        4.函數體中return下面的代碼雖然不再執行了,但是需要進行預解釋;return后面跟著的都是我們返回的值,所以不進行預解釋;

        function fn(){
        //預解釋:var num;
        console.log(num);//->undefined
        return function(){};
        var num=100;
        }

        5.函數聲明和變量聲明都會被提升。但是一個值得注意的細節(這個細節可以出現在有多個“重復”聲明的代碼中)是函數會首先被提升,然后才是變量。在預解釋的時候,如果名字已經聲明過了,不需要從新的聲明,但是需要重新的賦值;
        我們先來看下兩個簡單的例子:

        //例題1
         function a() {}
         var a
         console.log(typeof a)//'function'
        //例題2
         var c = 1
         function c(c) {
         console.log(c)
         var c = 3
         }
         c(2)//Uncaught TypeError: c is not a function

        當遇到存在函數聲明和變量聲明都會被提升的情況,函數聲明優先級比較高,最后變量聲明會被函數聲明所覆蓋,但是可以重新賦值,所以上個例子可以等價為

         function c(c) {
         console.log(c)
         var c = 3
         }
         c = 1
         c(2)

        接下來我們看下兩道比較復雜的題目:

        //例題3
        fn();
        function fn(){console.log(1);};
        fn();
        var fn=10;
        fn();
        function fn(){console.log(2);};
        fn();

        1.一開始預解釋,函數聲明和賦值一起來,fn 就是function fn(){console.log(1);};遇到var fn=10;不會重新再聲明,但是遇到function fn(){console.log(2);}就會從重新賦值,所以一開始fn()的值就是2

        2.再執行fn();值不變還是2

        3.fn重新賦值為10,所以運行fn()時報錯,接下去的語句就沒再執行。

        //例題4
        alert(a);
        a();
        var a=3;
        function a(){
        alert(10)
        }
        alert(a);
        a=6;
        a()

        1.函數聲明優先于變量聲明,預解釋時候,函數聲明和賦值一起來,a就是function a(){alert(10)} ,后面遇到var a=3,也無需再重復聲明,所以先彈出function a(){alert(10)}

        2.a() ,執行函數,然后彈出10

        3.接著執行了var a=3; 所以alert(a)就是顯示3

        4.由于a不是一個函數了,所以往下在執行到a()的時候, 報錯。

        參考文章

      4. JavaScript中的預解析
      5. http://heartwalker.cc/2016/04/04/js作用域其二-預解析/
      6. 總結

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        為什么說JavaScript預解釋是一種毫無節操的機制詳析

        為什么說JavaScript預解釋是一種毫無節操的機制詳析:前言 JavaScript是一門解釋型的語言 , 想要運行JavaScript代碼需要兩個階段 編譯階段: 編譯階段就是我們常說的JavaScript預解釋(預處理)階段,在這個階段JavaScript解釋器將完成把JavaScript腳本代碼轉換到字節碼 執行階段: 在編譯階段JavaScr
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 成年女人毛片免费播放视频m| 久久久久亚洲国产AV麻豆| 国产亚洲综合精品一区二区三区| 最近免费中文字幕mv电影| 亚洲五月综合缴情在线观看| 一级特黄色毛片免费看| 亚洲福利精品电影在线观看| 亚洲av成人片在线观看| 香蕉视频在线观看免费国产婷婷| 亚洲午夜一区二区电影院| 91香蕉成人免费网站| 国产婷婷综合丁香亚洲欧洲| 亚洲区小说区激情区图片区| 日韩在线视频免费| 亚洲精品成人a在线观看| 国产产在线精品亚洲AAVV| 国产v片免费播放| 直接进入免费看黄的网站| 国产一级淫片a免费播放口之| 鲁死你资源站亚洲av| 免费a级毛片永久免费| 污污污视频在线免费观看| 日日噜噜噜噜夜夜爽亚洲精品| 中文在线观看免费网站| 亚洲国产成人久久综合碰碰动漫3d| 99热亚洲色精品国产88| 无码中文字幕av免费放dvd| 亚洲一区二区三区免费观看| 美女被cao免费看在线看网站| 日本特黄特色aa大片免费| 国产精品日本亚洲777| 亚洲黄片毛片在线观看| 亚洲精品偷拍视频免费观看| 亚洲一区二区三区自拍公司| 一区二区三区在线免费看| 亚洲日产2021三区| 国产成人高清精品免费软件| 五级黄18以上免费看| 亚洲国产精品第一区二区| 嫩草视频在线免费观看| 一区二区三区视频免费|