函数声明和变量声明提升
顯示的是“function”,即function的優(yōu)先級高于var。?
有人覺得這是代碼順序執(zhí)行的原因,即a被后執(zhí)行的funcion覆蓋了。好,將它們調(diào)換下。
結(jié)果仍然顯示的是“function”而非“undefined”。即函數(shù)聲明優(yōu)先于變量聲明。?
我們把代碼稍作修改,聲明a時同時賦值。?
這時顯示的是“number”卻不是“function”了,這相當(dāng)于?
function a() { } var a; a = 1; // 注意此處 alert(typeof a);即把“var a = 1”拆分為兩步。 a被重新賦值了,自然是最后的那個值。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
變量聲明提升
1、變量定義
可以使用var定義變量,變量如果沒有賦值,那變量的初始值為undefined。
2、變量作用域
變量作用域指變量起作用的范圍。變量分為全局變量和局部變量。全局變量在全局都擁有定義;而局部變量只能在函數(shù)內(nèi)有效。?
在函數(shù)體內(nèi),同名的局部變量或者參數(shù)的優(yōu)先級會高于全局變量。也就是說,如果函數(shù)內(nèi)存在和全局變量同名的局部變量或者參數(shù),那么全局變量將會被局部變量覆蓋。?
所有不使用var定義的變量都視為全局變量
3、函數(shù)作用域和聲明提前
JavaScript的函數(shù)作用是指在函數(shù)內(nèi)聲明的所有變量在函數(shù)體內(nèi)始終是有定義的,也就是說變量在聲明之前已經(jīng)可用,所有這特性稱為聲明提前(hoisting),即javascript函數(shù)里的所有聲明(只是聲明,但不涉及賦值)都被提前到函數(shù)體的頂部,而變量賦值操作留在原來的位置。如下面例子:?
注釋:聲明提前是在JavaScript引擎的預(yù)編譯時進(jìn)行,是在代碼開始運(yùn)行之前。
由于函數(shù)內(nèi)聲明提升,所以上面的代碼實(shí)際上是這樣的
var scope = 'global'; function f(){ var scope; //變量聲明提升到函數(shù)頂部 console.log(scope); scope = 'local'; //變量初始化依然保留在原來的位置 console.log(scope); }經(jīng)過這樣變形之后,答案就就非常明顯了。由于scope在第一個console.log(scope)語句之前就已經(jīng)定義了,但是并沒有賦值,因此此時scope的指是undefined.第二個console.log(scope)語句之前,scope已經(jīng)完成賦值為’local’,所以輸出的結(jié)果是local。
函數(shù)聲明提升
1、函數(shù)的兩種創(chuàng)建方式
- 函數(shù)聲明
- 函數(shù)表達(dá)式
函數(shù)聲明語法
f('superman'); function f(name){ console.log(name); }運(yùn)行上面的程序,控制臺能打印出supemran。?
函數(shù)表達(dá)式語法
運(yùn)行上面的代碼,會報錯Uncaught ReferenceError: f is not defined(…),錯誤信息顯示說f沒有被定義。?
為什么同樣的代碼,函數(shù)聲明和函數(shù)表達(dá)式存在著差異呢??
這是因為,函數(shù)聲明有一個非常重要的特征:函數(shù)聲明提升,函數(shù)聲明語句將會被提升到外部腳本或者外部函數(shù)作用域的頂部(是不是跟變量提升非常類似)。正是因為這個特征,所以可以把函數(shù)聲明放在調(diào)用它的語句后面。如下面例子,最終的輸出結(jié)果應(yīng)該是什么?:
可能會有人覺得最后輸出的結(jié)果是1。讓我們來分析一下,這個例子涉及到了變量聲明提升和函數(shù)聲明提升。正如前面說到的函數(shù)聲明提升,函數(shù)聲明function getName(){}的聲明會被提前到頂部。而函數(shù)表達(dá)式var getName = function(){}則表現(xiàn)出變量聲明提升。因此在這種情況下,getName也是一個變量,因此這個變量的聲明也將提升到底部,而變量的賦值依然保留在原來的位置。因此上面的函數(shù)可以轉(zhuǎn)換成下面的樣子:
function getName(){ //函數(shù)聲明提升到頂部 console.log(1); } var getName; //變量聲明提升 getName = function(){ //變量賦值依然保留在原來的位置 console.log(2); } getName(); // 最終輸出:2所以最終的輸出結(jié)果是:2。在原來的例子中,函數(shù)聲明雖然是在函數(shù)表達(dá)式后面,但由于函數(shù)聲明提升到頂部,因此后面getName又被函數(shù)表達(dá)式的賦值操作給覆蓋了,所以輸出2。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
你不知道的JavaScript(上卷)????一書的第40頁中寫到:函數(shù)會首先被提升,然后才是變量。
console.log(foo); function foo(){console.log("函數(shù)聲明"); } var foo = "變量"輸出為:
function?foo(){
????console.log("函數(shù)聲明");
}
疑問:函數(shù)先提升,接著變量再提升,但函數(shù)優(yōu)先級比變量更高,所以console.log(foo)會是一個函數(shù);
這段代碼相當(dāng)于
function foo(){console.log("函數(shù)聲明"); } var foo; console.log(foo); foo = "變量"?
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
JavaScript中變量和函數(shù)聲明的提升
現(xiàn)象:
1.在JavaScript中變量和函數(shù)的聲明會提升到最頂部執(zhí)行。
2.函數(shù)的提升高于變量的提升。
3.函數(shù)內(nèi)部如果用var聲明了相同名稱的外部變量,函數(shù)將不再向上尋找。
4.匿名函數(shù)不會提升。
5.不同<script>塊中的函數(shù)互不影響。
函數(shù)聲明提升高于變量聲明
//同時聲明變量a和函數(shù)a var a; function a() {} alert(typeof a); //顯示的是"function",初步證明function的優(yōu)先級高于var。//先聲明函數(shù)后聲明變量,證明上邊的例子不是function覆蓋了變量 function a() {} var a; alert(typeof a); //顯示的仍是"function",而不是"undefined",即function的優(yōu)先級高于var。//聲明了變量的同時賦值 function a() {} var a = 1; alert(typeof a); //number,此時不是function了。 //說明:"var a=1"相當(dāng)于"var a;a=1",即先聲明,后賦值,"a=1"相當(dāng)于把a(bǔ)重新賦值了,自然就是number!函數(shù)內(nèi)部用var定義了和外部相同的變量,函數(shù)將不再向上找外部的變量
var value = 'hello'; function show() {alert(value);if (!value) {var value = 'function';}alert(value); } show() //此處調(diào)用函數(shù)依次彈出 "undefined", "function"//上例相當(dāng)于 var value = 'hello'; function show() {var value; //注意這行 alert(value);if (!value) {value = 'function'; //這行去掉var }alert(value); } show() //1.如果上列中show內(nèi)部定義value未用var,則會用到外部的變量,彈出"hello", "hello"。 //2.如果函數(shù)內(nèi)部未定義value,也能獲取到外部的value值。匿名函數(shù)不會向上提升
getName() var getName = function () {alert('closule') } function getName() {alert('function') } getName()//上邊的代碼相當(dāng)于 function getName() { //函數(shù)向上提升alert('function') } getName() var getName = function () {alert('closule') } getName()//代碼執(zhí)行分別彈出 "function", "closule"不同<script>塊中的函數(shù)互不影響
<script>getName()var getName = function () {alert('closule')} <script> <script>function getName() {alert('function')} <script>//代碼執(zhí)行報錯:TypeError: getName is not a function //因為第一個<script>塊中g(shù)etName()函數(shù)未定義,匿名函數(shù)又不會向上提升?
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
還有一個很疑惑的就是
function bar(){console.log(a);} bar(); var a = 33333; bar();輸出結(jié)果竟然是undefined和33333,為什么第二個能夠得到33333?
?---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function testOrder(arg) {console.log(arg); // arg是形參,不會被重新定義console.log(a); // 因為函數(shù)聲明比變量聲明優(yōu)先級高,所以這里a是函數(shù)var arg = 'hello'; // var arg;變量聲明被忽略, arg = 'hello'被執(zhí)行var a = 10; // var a;被忽視; a = 10被執(zhí)行,a變成numberfunction a() {console.log('fun');} // 被提升到作用域頂部console.log(a); // 輸出10console.log(arg); // 輸出hello }; testOrder('hi'); /* 輸出: hi function a() { console.log('fun'); } 10 hello */?
轉(zhuǎn)載于:https://www.cnblogs.com/aixiuxiu/p/7099138.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的函数声明和变量声明提升的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UVa 11168 Airport ,
- 下一篇: Spark Streaming学习笔记