首先要理解js中作用域的概念
作用域:指的是一個變量的作用范圍
1.全局作用域
直接寫在script中的js代碼,在js中,萬物皆對象,都在全局作用域,全局作用域在頁面打開時創建,在全局作用域中有一個全局對象window,它代表是一個瀏覽器的窗口
它由瀏覽器創建可以直接使用,在全局作用域中,創建的對象都可以都可以作為window對象的屬性保存,在任何地方都可以調用
2.函數作用域
調用函數時創建函數作用域,函數執行完畢后,函數作用域銷毀,每調用一次函數會創建一個新的函數作用域他們之間是相互獨立的,函數中可以訪問到全局作用域的變量,反之不行。當在函數作用域中操作對象,如果有,則使用,如果沒有則向其上一個作用域(不是指的是全局作用域)找,直到找到全局作用域無論在那個作用域,都有變量聲明提前現象,在函數中不用var聲明的變量都會設置為全局變量,形參相當于在函數作用域里聲明變量
var定義的變量可被更改,如果不初始化而直接使用也不會報錯,var聲明的變量會得到提升,其余兩個不存在這種情況,即必須先聲明再賦值
let定義的變量和var類似,但作用域在當前聲明的范圍內
const定義的變量只可初始化一次且作用域內不可被更改,使用前必須初始化
1.var的變量提升
js和其他語言一樣,都要經歷編譯和執行階段。而js在編譯階段的時候,會搜集所有的變量聲明并且提前聲明變量,而不會改變其他語句的順序,因此,在編譯階段的時候,第一步就已經執行了,而第二步則是在執行階段執行到該語句的時候才執行
經典案例
var即可用于函數外,亦可用于函數內,這就涉及到全局變量與局部變量的問題,
全局變量如何聲明:
在函數外聲明的變量就是全局變量,反之,在函數內聲明的變量就是局部變量,
作用域:全局變量無論在函數內,還是函數外,都可訪問到;
局部變量只能在函數內有效,函數外部訪問不到該變量及說對應的變量值
<script>
var a = 10;
function change() {
console.log(a);
var a = 7; //變量提升原因 例子1
}
change() //輸出為undefine
console.log(a);//輸出為10
</script>
<script>
var a = 10;
function change() {
a = 7; //改變了全局變量a的值
}
change();
console.log(a);//輸出為7
</script>
---------------------
<script>
var a = 10;
function change() {
var a = 7; //作用域的原因,a屬于函數作用域。
}
change();
console.log(a);//輸出為10 輸出的a是全局區域中的a,因為局部變量只能在函數內有效,函數外部訪問不到該變量及說對應的變量值
</script>
let是塊級作用域,函數內部使用let定義后,對函數外部無影響
ES6 新增了let命令,用來聲明變量。它的用法類似于var,但是所聲明的變量,只在let命令所在的代碼塊內有效。
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
不可以{
let a = 1;
let = 3;重復定義在一個塊級作用域
}
for循環的計數器,就很合適使用let命令
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
暫時性死區
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError//下面定義了let tmp 上面只要這種操作就是暫時性死區,為了讓我們編碼嚴格 const也是
let tmp;
}
為什么用塊級作用域?
1.例子1的變量提升,2就是for循環中的i
塊級作用域
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
如果是var,的話會輸出10
}
const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。
對于const來說,只聲明不賦值,就會報錯。
const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。
const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。
const聲明的常量,也與let一樣不可重復聲明。
本質
const實際上保證的,并不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對于簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,因此等同于常量。但對于復合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即總是指向另一個固定的地址),至于它指向的數據結構是不是可變的,就完全不能控制了。因此,將一個對象聲明為常量必須非常小心。
const foo = {};
// 為 foo 添加一個屬性,可以成功
foo.prop = 123;
foo.prop // 123
// 將 foo 指向另一個對象,就會報錯
foo = {}; // TypeError: "foo" is read-only
---------------------
覺得寫的還可以的朋友,請點贊加關注哦
如果文章中有疏忽寫錯的或者你不理解的還請評論區內交流哦






