摘要:代碼在執(zhí)行之前會先全局中變量提升函數(shù)聲明。函數(shù)的執(zhí)行上下文,也就是在這個函數(shù)范圍內(nèi)找到函數(shù)執(zhí)行上下文中函數(shù)范圍內(nèi),所有用聲明的變量。函數(shù)執(zhí)行時,按照執(zhí)行位置查找變量作用域只會向上查找。下一回變量作用域與閉包
上一章:JS的數(shù)據(jù)類型 傳送門:https://segmentfault.com/a/11...
好!話不多少,我們就開始吧。對變量提升和函數(shù)聲明的理解,能讓你更清楚容易的理解,為什么你的程序報錯了~哈哈哈
我們前端的代碼一般就三個部分組成html + css +js,一般呢我們的JS又會放在最后執(zhí)行。
執(zhí)行上下文:
所謂的執(zhí)行上下文,就是JS代碼執(zhí)行的環(huán)境。
Javascript中代碼的運行環(huán)境分為以下三種:
全局上下文 - 這個是默認的代碼運行環(huán)境,一旦代碼被載入,引擎最先進入的就是這個環(huán)境。
函數(shù)上下文 - 當執(zhí)行一個函數(shù)時,運行函數(shù)體中的代碼。
Eval上下文 - 在Eval函數(shù)內(nèi)運行的代碼。
這個和作用域有點像。
每次調(diào)用一個函數(shù)將會創(chuàng)建一個新的執(zhí)行上下文會,被添加到作用域鏈的頂部。
作用域和執(zhí)行上下文之間最大的區(qū)別是: 執(zhí)行上下文在運行時確定,隨時可能改變;作用域在定義時確定,永遠不會改變。
其實上面那些看看就好,直接看代碼吧。
JS代碼在執(zhí)行之前會先全局中變量提升、函數(shù)聲明。在函數(shù)中變量提升、函數(shù)聲明(this、函數(shù)參數(shù)也會提升,函數(shù)中的變量提升的范圍是這個函數(shù)的內(nèi)部)
變量提升:變量賦值的過程:聲明---初始化---賦值
舉例子:函數(shù)內(nèi)部的變量提升(全局的變量提升也是同理)
function fn(){ console.log(x);//undefined var x = 1; console.log(x);//1 } fn();
這里我們從針對變量x來解說:
1.在執(zhí)行fn時,為fn創(chuàng)建一個執(zhí)行環(huán)境。(fn函數(shù)的執(zhí)行上下文,也就是在fn這個函數(shù)范圍內(nèi))
2.找到fn函數(shù)執(zhí)行上下文中(fn函數(shù)范圍內(nèi)),所有用var聲明的變量。
3.將這些變量初始化為undefined。
4.開始執(zhí)行代碼。
5.把1賦值給變量x。
相當于如下這樣:
function fn(){ //把用var聲明的變量,提升到頂部,并初始化為undefined var x =undefined; //開始執(zhí)行代碼。 console.log(x);//undefined //把1賦值給變量x。 var x = 1; console.log(x);//1 } fn();
函數(shù)聲明:
cat();//123 function cat(){ console.log(123); } cat();//123
1.找到所有用function聲明的變量,并在環(huán)境中創(chuàng)建這些變量。
2.將這些變量初始化并賦值為function(){xxx}
3.在環(huán)境中從上往下開始執(zhí)行代碼。
相當于如下這樣:
//1.找到所有用function聲明的變量,并在環(huán)境中創(chuàng)建這些變量。 //2.將這些變量初始化并賦值為function(){xxx} var cat = function (){ console.log(123); } //3.在環(huán)境中從上往下開始執(zhí)行代碼。 cat();//123 cat();//123
這個就是函數(shù)聲明,在代碼執(zhí)行前,會把function提到頂部。所以如果不行代碼,代碼塊里即使有錯誤也不會報出來,只有執(zhí)行時才會運行代碼內(nèi)部東西。
看到這里應(yīng)該有個初步了解了,那么來看看下面的。加點難度,加深了解。
3543541
為什么fn中的globle拿不到呢?而fn2的globle能拿到值呢?
運用上面學(xué)習的知識來分析一波。
上面代碼在執(zhí)行前,會經(jīng)過變量提升、函數(shù)聲明,所以在準備執(zhí)行前的代碼是這樣的:
//函數(shù)聲明會在最最頂端 var fn = function (){ console.log(g); } var fn2 = function (){ console.log(g); } //執(zhí)行函數(shù)和變量按照相對位置排列 //執(zhí)行的相對位置不能變,這3個是在變量g之前執(zhí)行的就要一直在g之前執(zhí)行 fn2(); fn(); fn(); var g = undefined; console.log(g);//undefined var g = "global"; console.log(g);//global //執(zhí)行的相對位置不能變,這3個是在變量g之后執(zhí)行的就要一直在g之后執(zhí)行 fn2(); fn2(); fn();
這里我們可以總結(jié)出一點規(guī)律:
1.函數(shù)聲明會在最最頂端
2.變量提升,只是在自己的范圍內(nèi)提升
3.執(zhí)行的相對位置不能變和變量按照執(zhí)行上下文之前的相對位置排列。
4.函數(shù)執(zhí)行時,按照執(zhí)行位置查找變量作用域只會向上查找。
下一回:變量作用域與閉包
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/53134.html
摘要:代碼在執(zhí)行之前會先全局中變量提升函數(shù)聲明。函數(shù)的執(zhí)行上下文,也就是在這個函數(shù)范圍內(nèi)找到函數(shù)執(zhí)行上下文中函數(shù)范圍內(nèi),所有用聲明的變量。函數(shù)執(zhí)行時,按照執(zhí)行位置查找變量作用域只會向上查找。下一回變量作用域與閉包 上一章:JS的數(shù)據(jù)類型 傳送門:https://segmentfault.com/a/11... 好!話不多少,我們就開始吧。對變量提升和函數(shù)聲明的理解,能讓你更清楚容易的理解,...
摘要:代碼在執(zhí)行之前會先全局中變量提升函數(shù)聲明。函數(shù)的執(zhí)行上下文,也就是在這個函數(shù)范圍內(nèi)找到函數(shù)執(zhí)行上下文中函數(shù)范圍內(nèi),所有用聲明的變量。函數(shù)執(zhí)行時,按照執(zhí)行位置查找變量作用域只會向上查找。下一回變量作用域與閉包 上一章:JS的數(shù)據(jù)類型 傳送門:https://segmentfault.com/a/11... 好!話不多少,我們就開始吧。對變量提升和函數(shù)聲明的理解,能讓你更清楚容易的理解,...
摘要:上一章執(zhí)行上下文變量提升函數(shù)聲明傳送門本次我們主要講講變量作用域和閉包變量作用域顧名思義變量起作用的范圍。則是局部變量,只能在函數(shù)中使用。閉包則能長久保存變量,又不會污染。舉例子定義外層函數(shù),封裝被保護的局部變量。 上一章 JS執(zhí)行上下文、變量提升、函數(shù)聲明 傳送門:https://segmentfault.com/a/11... 本次我們主要講講變量作用域和閉包變量作用域:顧名思義:...
摘要:上一章執(zhí)行上下文變量提升函數(shù)聲明傳送門本次我們主要講講變量作用域和閉包變量作用域顧名思義變量起作用的范圍。則是局部變量,只能在函數(shù)中使用。閉包則能長久保存變量,又不會污染。舉例子定義外層函數(shù),封裝被保護的局部變量。 上一章 JS執(zhí)行上下文、變量提升、函數(shù)聲明 傳送門:https://segmentfault.com/a/11... 本次我們主要講講變量作用域和閉包變量作用域:顧名思義:...
閱讀 1093·2021-10-12 10:11
閱讀 877·2019-08-30 15:53
閱讀 2286·2019-08-30 14:15
閱讀 2961·2019-08-30 14:09
閱讀 1197·2019-08-29 17:24
閱讀 972·2019-08-26 18:27
閱讀 1283·2019-08-26 11:57
閱讀 2146·2019-08-23 18:23