var let const声明变量的区别
在js中定義變量的方式有三種,其中l(wèi)et和const關(guān)鍵字是來(lái)自ES6中的,下面將逐一介紹各個(gè)關(guān)鍵字聲明變量的特點(diǎn)。
var聲明變量
var 是一個(gè) JS關(guān)鍵字,用來(lái)聲明變量( variable 變量的意思 )。使用該關(guān)鍵字聲明變量后,計(jì)算機(jī)會(huì)自動(dòng)為變量分配內(nèi)存空間,不需要程序員。
1.js可以允許變量不聲明直接使用
2.js中使用var聲明的變量沒有塊級(jí)作用域
Js中沒有塊級(jí)作用域(在ES6之前)。
if(true){var num = 123;console.log(123); //123 } console.log(123); //123由于js中沒有塊級(jí)作用域,所以在if內(nèi)部定義的變量,在外部也可以直接調(diào)用進(jìn)行訪問。
let聲明變量
ES6中新增用于聲明變量的關(guān)鍵字let.
1.let聲明的變有塊級(jí)作用域
在es6之前,聲明的變量是沒有塊級(jí)作用域的概念,但是在es6中用let聲明的關(guān)鍵字有塊級(jí)作用域。
? 塊作用域指的是由 { } 包括。
? 在其他編程語(yǔ)言中(如 java、c#等),在 if 語(yǔ)句、循環(huán)語(yǔ)句中創(chuàng)建的變量,僅僅只能在本 if 語(yǔ)句、本循環(huán)語(yǔ)句中使用,如下面的Java代碼:
java有塊級(jí)作用域:
if(true){int num = 123;system.out.print(num); // 123 } system.out.print(num); // 報(bào)錯(cuò)以上java代碼會(huì)報(bào)錯(cuò),是因?yàn)榇a中 { } 即一塊作用域,其中聲明的變量 num,在 “{ }” 之外不能使用;
而與之類似的JavaScript代碼由于沒有塊級(jí)作用域的概念,則不會(huì)報(bào)錯(cuò)(Js中沒有塊級(jí)作用域(在ES6之前))
if(true){var num = 123;console.log(123); //123 }console.log(123); //123但是ES6中固定使用let關(guān)鍵字聲明的變量有塊級(jí)作用域
if (true) { let a = 10;} console.log(a) // a is not defined注意:使用let關(guān)鍵字聲明的變量才具有塊級(jí)作用域,使用var聲明的變量不具備塊級(jí)作用域特性。
2.let聲明變量不存在變量提升
JavaScript 代碼是由瀏覽器中的 JavaScript 解析器來(lái)執(zhí)行的。JavaScript 解析器在運(yùn)行 JavaScript 代碼的時(shí)候分為兩步:預(yù)解析和代碼執(zhí)行。
- 預(yù)解析:在當(dāng)前作用域下, JS 代碼執(zhí)行之前,瀏覽器會(huì)默認(rèn)把帶有 var 和 function 聲明的變量在內(nèi)存中進(jìn)行提前聲明或者定義。
- 代碼執(zhí)行: 從上到下執(zhí)行JS語(yǔ)句。
注意: 預(yù)解析會(huì)把變量和函數(shù)的聲明在代碼執(zhí)行之前執(zhí)行完成。
變量預(yù)解析:
預(yù)解析也叫做變量、函數(shù)提升。
變量提升(變量預(yù)解析): 變量的聲明會(huì)被提升到當(dāng)前作用域的最上面,變量的賦值不會(huì)提升。
由于javascript有變量提升機(jī)制,所以可以在變量的聲明之前就調(diào)用該變量,因?yàn)樽兞刻嵘龝?huì)將變量的聲明提升到最前面,但是變量的提升不會(huì)對(duì)值進(jìn)行提升,所以變量沒有賦值之前的默認(rèn)值是undefined.
但是由于變量的提升導(dǎo)致在日常的開發(fā)中,會(huì)遇到很多奇怪的問題,所有ES6規(guī)定,使用let關(guān)鍵字聲明的變量沒有變量的提升。
console.log(a); // a is not defined let a = 20;注意:使用let關(guān)鍵字聲明的變量才沒變量的提升,使用var關(guān)鍵字聲明的變量依舊有變量的提升。
3.暫時(shí)性死區(qū)
在js中采取從上一級(jí)就近原則的方式來(lái)查找變量最終的值。
但是利用let聲明的變量會(huì)綁定在這個(gè)塊級(jí)作用域,不會(huì)受外界的影響。
var temp = 123;if (true) {temp = "abc";let temp;console.log(temp);}按照以前的就近原則的特點(diǎn),此時(shí)控制臺(tái)因該輸出“abc”,但是結(jié)果真的是這樣嗎?
在ES6中規(guī)定,使用let關(guān)鍵字聲明的變量在塊級(jí)作用域中具有暫時(shí)性死區(qū)的特性。簡(jiǎn)單來(lái)講,就是在塊級(jí)作用域中使用let聲明的關(guān)鍵字要符合let關(guān)鍵字的性質(zhì),和以前的不一樣。
例如:上面的例子由于在塊級(jí)作用域聲明了temp變量,但是在聲明temp之前,盡然對(duì)temp變量賦值“abc”,這就觸犯了let關(guān)鍵字沒有變量提升的規(guī)則,在還沒聲明變量之前就給未聲明的變量賦值,報(bào)錯(cuò)。
不能再初始化之前訪問“temp”.
注意:只有使用let關(guān)鍵字聲明的變量才有暫時(shí)性死區(qū)的特性。
4.let可以防止循環(huán)變量變成全局變量
經(jīng)典面試題圖解:此題的關(guān)鍵點(diǎn)在于每次循環(huán)都會(huì)產(chǎn)生一個(gè)塊級(jí)作用域,每個(gè)塊級(jí)作用域中的變量都是不同的,函數(shù)執(zhí)行時(shí)輸出的是自己上一級(jí)(循環(huán)產(chǎn)生的塊級(jí)作用域)作用域下的i值.
5.小結(jié)
- let關(guān)鍵字就是用來(lái)聲明變量的
- 使用let關(guān)鍵字聲明的變量具有塊級(jí)作用域
- 在一個(gè)大括號(hào)中 使用let關(guān)鍵字聲明的變量才具有塊級(jí)作用域 var關(guān)鍵字是不具備這個(gè)特點(diǎn)的
- 防止循環(huán)變量變成全局變量
- 使用let關(guān)鍵字聲明的變量沒有變量提升
- 使用let關(guān)鍵字聲明的變量具有暫時(shí)性死區(qū)特性
const聲明常量
聲明常量,常量就是值(內(nèi)存地址)不能變化的量。
1.具有塊級(jí)作用域
if (true) { const a = 10;} console.log(a) // a is not defined2.聲明變量的時(shí)候必須賦值
const PI; // Missing initializer in const declaration3.常量賦值后,值不能修改
const PI = 3.14; PI = 100; // Assignment to constant variable.const ary = [100, 200]; ary[0] = 'a'; ary[1] = 'b'; console.log(ary); // ['a', 'b']; ary = ['a', 'b']; // Assignment to constant variable.由于使用const聲明的常量賦值之后不能修改,這就有點(diǎn)像java中使用private修飾的變量。例如上面的例子,PI由于聲明的時(shí)候進(jìn)行了賦值操作,所以就不能進(jìn)行二次賦值操作,但是對(duì)于數(shù)組而言由于const關(guān)鍵字聲明的常量是ary,所以對(duì)于ary是不能進(jìn)行二次賦值,但是對(duì)于數(shù)組儲(chǔ)存的值是不屬于const管的。const管理的只是const聲明的變量不能二次賦值,而對(duì)于變量中儲(chǔ)存的是什么,是沒有約束力的。
4.小結(jié)
- const聲明的變量是一個(gè)常量
- 既然是常量不能重新進(jìn)行賦值,如果是基本數(shù)據(jù)類型,不能更改值,如果是復(fù)雜數(shù)據(jù)類型,不能更改地址值。
- 聲明 const時(shí)候必須要給定值
let、const、var 的區(qū)別
- 使用 var 聲明的變量,其作用域?yàn)樵撜Z(yǔ)句所在的函數(shù)內(nèi),且存在變量提升現(xiàn)象
- 使用 let 聲明的變量,其作用域?yàn)樵撜Z(yǔ)句所在的代碼塊內(nèi),不存在變量提升
- 使用 const 聲明的是常量,在后面出現(xiàn)的代碼中不能再修改該常量的值
總結(jié)
以上是生活随笔為你收集整理的var let const声明变量的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Maven插件tomcat7-maver
- 下一篇: 发送ajax请求的四种方式