摘要:命令用于規(guī)定模塊的對(duì)外接口,命令用于輸入其他模塊提供的功能所以在一定程度上來(lái)說(shuō),也具有聲明變量的功能。當(dāng)沒(méi)有聲明,直接給變量賦值時(shí),會(huì)隱式地給變量聲明,此時(shí)這個(gè)變量作為全局變量存在。
前言
如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處,還請(qǐng)看到的小伙伴多多指教,先行謝過(guò)
在ES5階段,JavaScript 使用 var 和 function 來(lái)聲明變量, ES6 中又添加了let、const、import、 Class 這幾種聲明變量的方式。那么,他們各自都有什么樣的特點(diǎn)呢?
下面,就讓我們一起去探究一下吧
以下↓
變量就是存儲(chǔ)信息的容器。 ECMAScript 的變量是松散類型的,所謂松散類型就是可以用來(lái)保存任何類型的數(shù)據(jù)var 聲明
一直以來(lái),我們都是使用var關(guān)鍵字來(lái)聲明變量
var a = 1; var b; console.log(a) // 1 console.log(b) // undefined console.log(c) // undefined var b = 2; var c = 3; console.log(b) // 2 console.log(c) // 3 function f() { var c = 4; console.log(c) // 4 c = 5; console.log(c) // 5 } f(); console.log(c) // 3 function fun() { c = 6 } fun(); console.log(c) // 6
從上面的結(jié)果我們不難看出,使用var聲明的變量具有以下特點(diǎn):
變量可以沒(méi)有初始值,會(huì)保存一個(gè)特殊的值 undefined
變量可以重復(fù)定義,且可以修改值
變量聲明語(yǔ)句從自動(dòng)提升到所在作用域的頂端
函數(shù)內(nèi)重復(fù)定義對(duì)函數(shù)外無(wú)影響(局部變量)
函數(shù)內(nèi)重新賦值對(duì)函數(shù)外有影響
function 關(guān)鍵字聲明在ES5中,除了使用var聲明變量,我們也可以使用 function 關(guān)鍵字聲明變量
f(); function f() {console.log(1)} var f; console.log(f) // function f
特點(diǎn):
使用 function 聲明的是函數(shù)對(duì)象,也存在聲明提升
函數(shù)聲明要優(yōu)于變量聲明
let聲明由于 ES5 中使用 var 聲明變量存在著一些很讓人迷惑的特性(比如變量提升,重復(fù)定義等),ES6 中新增 let 命令,用來(lái)聲明變量。它的用法類似于 var ,但是所聲明的變量,只在 let 命令所在的代碼塊內(nèi)有效
{ var a = 1; let b = 2; } console.log(a) // 1 console.log(b) // Uncaught ReferenceError: b is not defined console.log(c) // Uncaught ReferenceError: c is not defined let c = 3 let a = 4 console.log(a) // Identifier "a" has already been declared
通過(guò)以上的代碼,我們很容易發(fā)現(xiàn)使用 let 聲明變量的特點(diǎn):
let聲明的變量只在它所在的代碼塊有效
不存在變量提升
不可以重復(fù)聲明
由于 let 聲明變量的這些特點(diǎn),所以 for 循環(huán)的計(jì)數(shù)器,就很合適使用 let 命令
for(let i = 0; i < 10; i++) { // } console.log(i) // Uncaught ReferenceError: c is not defined // 如果使用var聲明,則在這里輸出的就是10
let 實(shí)際上為 JavaScript 新增了塊級(jí)作用域const聲明
const 也是 ES6 新增的聲明變量的方式,const 聲明一個(gè)只讀的常量。一旦聲明,常量的值就不能改變
const API; console.log(API) // SyntaxError: Missing initializer in const declaration console.log(MAX); // Uncaught ReferenceError: MAX is not defined const MAX = 1; const MAX = 2; console.log(MAX); // Identifier "MAX" has already been declared const PI = 3.1415; console.log(PI) // 3.1415 PI = 3; // TypeError: Assignment to constant variable. const f = {} f.name = "HELLO" // 正常執(zhí)行 f = {name: "World"} // 報(bào)錯(cuò)
所以,使用 const 聲明的變量具有以下特點(diǎn):
const 一旦聲明變量,就必須立即初始化,不能留到以后賦值
不允許重復(fù)聲明
不存在變量提升
const 實(shí)際上保證的,并不是變量的值不得改動(dòng),而是變量指向的那個(gè)內(nèi)存地址不得改動(dòng)
如果真的想將對(duì)象凍結(jié),應(yīng)該使用 Object.freeze 方法import 聲明
ES6 新增的模塊的概念。
模塊功能主要由兩個(gè)命令構(gòu)成:export 和 import。 export 命令用于規(guī)定模塊的對(duì)外接口,import 命令用于輸入其他模塊提供的功能
所以在一定程度上來(lái)說(shuō),import 也具有聲明變量的功能。只是在使用 import 的時(shí)候,具有一些限制
export { first, last } import { first, last } from "./xxx" first = {} // Syntax Error : "a" is read-only; first.name = "Hello" // 成功執(zhí)行,但是不建議這樣使用 export default function(){} // a.js import xxx from "a.js" import { New as $ } from "./xxx"
特點(diǎn):
import 命令接受一對(duì)大括號(hào),大括號(hào)里面的變量名,必須與被導(dǎo)入模塊對(duì)外接口的名稱相同
import 命令輸入的變量都是只讀的,因?yàn)樗谋举|(zhì)是輸入接口
當(dāng)使用 export default 命令,為模塊指定默認(rèn)輸出的時(shí)候,import 命令可以為該匿名函數(shù)指定任意名字
import 命令具有提升效果,會(huì)提升到整個(gè)模塊的頭部,首先執(zhí)行
如果想為輸入的變量重新取一個(gè)名字,import 命令要使用 as 關(guān)鍵字,將輸入的變量重命名
本質(zhì)上,export default 就是輸出一個(gè)叫做 default 的變量或方法,然后系統(tǒng)允許你為它取任意名字class 聲明
ES6 引入了類的概念,有了 class 這個(gè)關(guān)鍵字,作為對(duì)象的模板。通過(guò) class 關(guān)鍵字,可以定義類
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return "(" + this.x + ", " + this.y + ")"; } }
ES6 的 class 可以看作只是一個(gè)語(yǔ)法糖,它的絕大部分功能,ES5 都可以做到,類的實(shí)質(zhì)還是函數(shù)對(duì)象,類中的方法和對(duì)象其實(shí)都是掛在對(duì)應(yīng)的函數(shù)對(duì)象的 prototype 屬性下
所以就可以改寫(xiě)成下面這種ES5的方式
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function() { return "(" + this.x + ", " + this.y + ")"; }
特點(diǎn):
所有類都有 constructor 函數(shù),如果沒(méi)有顯式定義,一個(gè)空的 constructor 方法會(huì)被默認(rèn)添加。當(dāng)然所有函數(shù)對(duì)象都必須有個(gè)主體
生成類的實(shí)例對(duì)象的寫(xiě)法,與 ES5 通過(guò)構(gòu)造函數(shù)生成對(duì)象完全一樣,也是使用 new 命令
class B {} let b = new B();
在類的實(shí)例上面調(diào)用方法,其實(shí)就是調(diào)用原型上的方法
與函數(shù)對(duì)象一樣,Class 也可以使用表達(dá)式的形式定義
Class 其實(shí)就是一個(gè) function ,但是有一點(diǎn)不同,Class 不存在變量提升,也就是說(shuō) Class 聲明定義必須在使用之前
全局變量在瀏覽器環(huán)境指的是 window 對(duì)象,在 Node 指的是 global 對(duì)象。ES5 之中,頂層對(duì)象的屬性與全局變量是等價(jià)的var 命令和 function 命令聲明的全局變量,依舊是頂層對(duì)象的屬性;另一方面規(guī)定,let 命令、const 命令、class 命令聲明的全局變量,不屬于頂層對(duì)象的屬性。也就是說(shuō),從 ES6 開(kāi)始,全局變量將逐步與頂層對(duì)象的屬性脫鉤
var a = 1; window.a // 1 let b = 2; window.b // undefined隱式聲明
在 JavaScript 中還存在著隱式聲明。
a = 1; console.log(a) // 1
當(dāng)沒(méi)有聲明,直接給變量賦值時(shí),會(huì)隱式地給變量聲明,此時(shí)這個(gè)變量作為全局變量存在。這個(gè)時(shí)候就不存在聲明提前的問(wèn)題了最后
其實(shí)只要我們理解并掌握了這幾種聲明變量的方式,記住它們的特點(diǎn),那么在實(shí)際使用的過(guò)程當(dāng)中就很容易能夠找到最合適的方式去定義
每天學(xué)習(xí)分享,不定期更新
最后,推薦一波前端學(xué)習(xí)歷程,這段時(shí)間總結(jié)的一些面試相關(guān),分享給有需要的小伙伴,歡迎 star 關(guān)注 傳送門(mén)
參考文檔ECMAScript 6入門(mén)
ES6變量聲明
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/109258.html
摘要:變量作用域詳解作用域規(guī)則大部分情況下沒(méi)有塊級(jí)作用域除非你使用當(dāng)你使用的情況下僅僅支持函數(shù)作用域不使用聲明的變量為全局變量不用情況下中局部變量只能通過(guò)和函數(shù)參數(shù)聲明大部分情況下沒(méi)有塊級(jí)作用域除非你使用與很多語(yǔ)言不同在之前并沒(méi)有塊級(jí)作用域一個(gè)作 Javascript變量作用域詳解 JS作用域規(guī)則 JS大部分情況下沒(méi)有塊級(jí)作用域, 除非你使用let 當(dāng)你使用var的情況下, JS僅僅支持函...
摘要:概述發(fā)布前,只能通過(guò)聲明變量的方式,常量塊級(jí)變量函數(shù)變量這些概念的差別都不能很好的體現(xiàn)出來(lái),于此同時(shí),加入你要使用或者提供一個(gè),聲明的變量可隨時(shí)被修改和重新分配的問(wèn)題,會(huì)讓你時(shí)刻擔(dān)心代碼是否能正常運(yùn)行。 1. var、let、const概述 ES6發(fā)布前,Javascript只能通過(guò)var聲明變量的方式,常量、塊級(jí)變量、函數(shù)變量這些概念的差別都不能很好的體現(xiàn)出來(lái),于此同時(shí),加入你要使用...
摘要:不同的是函數(shù)體并不會(huì)再被提升至函數(shù)作用域頭部,而僅會(huì)被提升到塊級(jí)作用域頭部避免全局變量在計(jì)算機(jī)編程中,全局變量指的是在所有作用域中都能訪問(wèn)的變量。 ES6 變量作用域與提升:變量的生命周期詳解從屬于筆者的現(xiàn)代 JavaScript 開(kāi)發(fā):語(yǔ)法基礎(chǔ)與實(shí)踐技巧系列文章。本文詳細(xì)討論了 JavaScript 中作用域、執(zhí)行上下文、不同作用域下變量提升與函數(shù)提升的表現(xiàn)、頂層對(duì)象以及如何避免創(chuàng)建...
摘要:知識(shí)點(diǎn)聲明的變量在預(yù)解析的時(shí)候只執(zhí)行聲明,不會(huì)執(zhí)行定義,默認(rèn)值是。聲明的函數(shù)在預(yù)解析的時(shí)候會(huì)提前聲明并且會(huì)同時(shí)定義。 showImg(https://segmentfault.com/img/bVbnY76?w=2500&h=1250); 知識(shí)點(diǎn) var 聲明的變量在預(yù)解析的時(shí)候只執(zhí)行聲明,不會(huì)執(zhí)行定義,默認(rèn)值是 undefined。 function 聲明的函數(shù)在預(yù)解析的時(shí)候會(huì)...
摘要:換句話說(shuō),在代碼執(zhí)行之前,會(huì)對(duì)作用域鏈中所有變量和函數(shù)聲明先處理完先??偨Y(jié)一句話就是只有聲明被提升,而賦值或其他運(yùn)算會(huì)留在原地。為其聲明變量隱性劫持到所在區(qū)域中。 之前一直覺(jué)會(huì)認(rèn)為javascript代碼執(zhí)行是由上到下一行行執(zhí)行的。自從看了《你不知道的JS》后發(fā)現(xiàn)這個(gè)觀點(diǎn)并不完全正確。先來(lái)給大家舉一個(gè)書(shū)本上的的例子: var a=hello world; var a; co...
閱讀 2479·2021-09-30 09:47
閱讀 3034·2019-08-30 11:05
閱讀 2639·2019-08-29 17:20
閱讀 2050·2019-08-29 13:01
閱讀 1809·2019-08-26 13:39
閱讀 1421·2019-08-26 13:26
閱讀 3305·2019-08-23 18:40
閱讀 1969·2019-08-23 17:09