引言:這裏主要研究變量,剛學完js中的對象和屬性,不要弄混,這裏主要說的是棧內存的,而對象和對象的屬性在堆內存中。
變量提升
變量提升是指:通過var 定義的變量。在變量定義語句之前可以訪問到,只不過訪問到的是undefined,
在全局作用域中用var關鍵字定義的變量會在所有代碼執行之前,首先聲明變量。
<script>
console.log(a)//這裏輸出a的值爲undefined
console.log(b)//會報錯
var a = 3
b = 6
</script>
其實上面這段代碼,在運行時會變成如下
<script>
var a
console.log(a)//這裏輸出a的值爲undefined
console.log(b)//會報錯
a = 3
b = 6
</script>
用var 聲明的變量會到程序最開始聲明
在函數作用域中變量提升同樣存在
<script>
function fn(){
console.log(a)//這裏輸出a的值爲undefined
var a = 3
}
</script>
上面的代碼類似於
<script>
function fn(){
var a
console.log(a)//這裏輸出a的值爲undefined
a = 3
}
</script>
從上面的例子可以看出變量在全局作用域和函數作用域都有變量提升的特性,同樣的方法也有這種特性,只不過js中要求只有聲明式方法有函數提升的特性,如:function fn (){}就是聲明式函數。對於用var fn = function(){}的函數,它用的是變量提升特性
函數提升
<script>
fn()//控制檯會輸出 你好
function fn(){
console.log("你好")
}
fn2()//控制檯輸出 undefined
var fn2 = function(){
console.log("fn2")
}
</script>
因爲函數fn在調用之前就已經產生了。而對於fn2它依照變量提升的特性,只是提前聲明瞭,沒有定義變量值,所以輸出undefined。同時在函數作用域依然支持函數提升。上面代碼類似於如下:
<script>
var fn2//變量提升
//函數提升
function fn(){
console.log("你好")
}
fn()//控制檯會輸出 你好
fn2()//控制檯輸出 undefined
fn2 = function(){
console.log("fn2")
}
</script>
作用域問題
作用域分爲全局作用域和局部作用域。
全局作用域和局部作用域的概念就不說了。這裏主要說一下js中的特殊之處
1.全局作用域打開瀏覽器產生,關閉瀏覽器銷燬
2.局部作用域方法執行產生,方法執行完成後銷燬
3.在js的全局作用域中有一個全局作用域對象window,該對象會把全局作用域中的變量和函數作爲它本身的屬性保存。
變量分爲全局變量和局部變量。
由上面的全局變量用var定義時會變量提升,所以window對象中在程序開始執行前就存在了var定義的全局變量和聲明式定義的函數。
全局執行上下文(window)
全局執行上下文:window對象,相當於一個容器,用來存放全局的變量等等
全局作用域執行的步驟
1.在執行全局代碼前先把window對象確定爲上下文
2.對全局變量進行預處理,
把var定義的全局變量定義未undefined(由於變量提升),然後添加到window對象的屬性中
把function聲明的全局函數,賦值,添加爲window的方法
把this,賦值爲window對象
3.開始執行全局代碼
函數執行上下文