這篇文章主要介紹了JavaScript預(yù)解釋指的是什么,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
站在用戶的角度思考問題,與客戶深入溝通,找到長洲網(wǎng)站設(shè)計與長洲網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都做網(wǎng)站、網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名注冊、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋長洲地區(qū)。
JavaScript是一門解釋型的語言 , 想要運行JavaScript代碼需要兩個階段
編譯階段: 編譯階段就是我們常說的JavaScript預(yù)解釋(預(yù)處理)階段,在這個階段JavaScript解釋器將完成把JavaScript腳本代碼轉(zhuǎn)換到字節(jié)碼
執(zhí)行階段: 在編譯階段JavaScript解釋器借助執(zhí)行環(huán)境把字節(jié)碼生成機械碼,并從上到下按順序執(zhí)行
本文就重點介紹預(yù)解釋,框架圖如下:
預(yù)解釋:JavaScript代碼執(zhí)行之前,瀏覽器首先會默認(rèn)的把所有帶var和function的進行提前的聲明或者定義
聲明(declare):如var num;=>告訴瀏覽器在全局作用域中有一個num的變量了;如果一個變量只是聲明了但是沒有賦值,默認(rèn)的值是undefined
定義(defined):如num=12;=>給我們的變量進行賦值。
var =>在預(yù)解釋的時候只是提前的聲明
function =>在預(yù)解釋的時候提前的聲明+定義都完成了
例如:開始只對window下的進行預(yù)解釋,只有函數(shù)執(zhí)行的時候才會對函數(shù)中的進行預(yù)解釋
1)在全局作用域下聲明(預(yù)解釋的時候)的變量是全局變量
2)只有函數(shù)執(zhí)行會產(chǎn)生私有的作用域,比如for(){}、if(){}和switch(){}都不會產(chǎn)生私有作用域
3)在"私有作用域中聲明的變量(var 聲明)"和"函數(shù)的形參"都是私有的變量。在私有作用域中,代碼執(zhí)行的時保遇到了一個變量,首先我們需要確定它是否為私有的變量,如果是私有的變量,那么和外面的沒有在何的關(guān)系;如果不是私有的,則往當(dāng)前作用域的上級作用域進行查找,如果上級作用域也沒有則繼續(xù)查找,一直找到window為止,這就是作用域鏈。
我們舉個例子來區(qū)別私有變量和全局變量:
//=>變量提升: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
判斷是否是私有變量一個標(biāo)準(zhǔn)就是是否是在函數(shù)中var聲明的變量和函數(shù)的形參都是私有的變量。本道題目在test函數(shù)中a是形參和var b定義的變量b都是私有變量。
這是因為當(dāng)函數(shù)執(zhí)行的時候,首先會形成一個新的私有的作用域,然后按照如下的步驟執(zhí)行:
1)如果有形參,先給形參賦值
2)進行私有作用域中的預(yù)解釋
3)私有作用域中的代碼從上到下執(zhí)行
我們來看一道例題
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 私有的也修改不了外面的
棧內(nèi)存:用來提供一個供JS代碼執(zhí)行的環(huán)境,即作用域(全局作用域/私有的作用域)
堆內(nèi)存:用來存儲引用數(shù)據(jù)類型的值。對象存儲的是屬性名和屬性值,函數(shù)存儲的是代碼字符串。
我們先來看以下兩個例子:
//例題1 console.log(num);//->undefined var num=12;
//例題2 console.log(num2);//->Uncaught ReferenceError:num2 is not defined num2=12;//不能預(yù)解釋
當(dāng)你看到var num=12時,可能會認(rèn)為只是個聲明。但JavaScript實際上會將其看成兩條聲明語句:var num;和 num=12;第一個定義聲明是在預(yù)解釋階段進行的。第二個賦值聲明會被留在原地等待執(zhí)行階段。num2=12 相當(dāng)于給window增加了一個叫做num2的屬性名,屬性值是12;而var num=12 首先它相當(dāng)于給全局作用域增加了一個全局變量num,它也相當(dāng)于給window增加了一個屬性名num2,屬性值是12。兩者最大區(qū)別:帶var的可以進行預(yù)解釋,所以在賦值的前面執(zhí)行不會報錯;不帶var的是不能進行預(yù)解釋的,在前面執(zhí)行會報錯;
接下來我們舉例說明:
//例題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變量在私有作用域中可以預(yù)解釋,所以第一個console打出來的值為undefined。私有作用域中出現(xiàn)的一個變量不是私有的,則往上級作用域進行查找,上級沒有則繼續(xù)向上查找,一直找到window為止,例題2中不帶var變量不是私有的,所以往上級找
請看下面這道例題:
if(!("num" in window)){ var num=12;//這句話會被提到大括號之外的全局作用域:var num;->window.num; } console.log(num);//undefined
請看下面這道例題:
fn();//報錯 var fn=function (){ //window下的預(yù)解釋:var fn; console.log("ok"); };
自執(zhí)行函數(shù)定義的那個function在全局作用域下不進行預(yù)解釋,當(dāng)代碼執(zhí)行到這個位置的時候定義和執(zhí)行一起完成了。常見有以下幾種形式:
(function(num){})(10); ~function(num){}(10); +function(num){}(10); -function(num){}(10); !function(num){}(10);
function fn(){ //預(yù)解釋:var num; console.log(num);//->undefined return function(){}; var num=100; }
我們先來看下兩個簡單的例子:
//例題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
當(dāng)遇到存在函數(shù)聲明和變量聲明都會被提升的情況,函數(shù)聲明優(yōu)先級比較高,最后變量聲明會被函數(shù)聲明所覆蓋,但是可以重新賦值,所以上個例子可以等價為
function c(c) { console.log(c) var c = 3 } c = 1 c(2)
接下來我們看下兩道比較復(fù)雜的題目:
//例題3 fn(); function fn(){console.log(1);}; fn(); var fn=10; fn(); function fn(){console.log(2);}; fn();
1.一開始預(yù)解釋,函數(shù)聲明和賦值一起來,fn 就是function fn(){console.log(1);};遇到var fn=10;不會重新再聲明,但是遇到function fn(){console.log(2);}就會從重新賦值,所以一開始fn()的值就是2
2.再執(zhí)行fn();值不變還是2
3.fn重新賦值為10,所以運行fn()時報錯,接下去的語句就沒再執(zhí)行。
//例題4 alert(a); a(); var a=3; function a(){ alert(10) } alert(a); a=6; a()
1.函數(shù)聲明優(yōu)先于變量聲明,預(yù)解釋時候,函數(shù)聲明和賦值一起來,a就是function a(){alert(10)} ,后面遇到var a=3,也無需再重復(fù)聲明,所以先彈出function a(){alert(10)}
2.a(),執(zhí)行函數(shù),然后彈出10
3.接著執(zhí)行了var a=3; 所以alert(a)就是顯示3
4.由于a不是一個函數(shù)了,所以往下在執(zhí)行到a()的時候, 報錯。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享JavaScript預(yù)解釋指的是什么內(nèi)容對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,遇到問題就找創(chuàng)新互聯(lián),詳細(xì)的解決方法等著你來學(xué)習(xí)!