若是文章中有出現紕漏、錯誤之處,還請看到的小夥伴多多指教,先行謝過前端
在ES5
階段,JavaScript
使用 var
和 function
來聲明變量, ES6
中又添加了let
、const
、import
、 Class
這幾種聲明變量的方式。那麼,他們各自都有什麼樣的特色呢?git
下面,就讓咱們一塊兒去探究一下吧es6
如下↓github
變量就是存儲信息的容器。
ECMAScript
的變量是鬆散類型的,所謂鬆散類型就是能夠用來保存任何類型的數據web
一直以來,咱們都是使用var關鍵字來聲明變量面試
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
複製代碼
從上面的結果咱們不難看出,使用var聲明的變量具備如下特色:瀏覽器
undefined
在ES5中,除了使用var聲明變量,咱們也可使用 function
關鍵字聲明變量函數
f();
function f() {console.log(1)}
var f;
console.log(f) // function f
複製代碼
特色:學習
function
聲明的是函數對象,也存在聲明提高因爲 ES5
中使用 var
聲明變量存在着一些很讓人迷惑的特性(好比變量提高,重複定義等),ES6
中新增 let
命令,用來聲明變量。它的用法相似於 var
,可是所聲明的變量,只在 let
命令所在的代碼塊內有效ui
{
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
複製代碼
經過以上的代碼,咱們很容易發現使用 let
聲明變量的特色:
因爲 let
聲明變量的這些特色,因此 for
循環的計數器,就很合適使用 let
命令
for(let i = 0; i < 10; i++) {
//
}
console.log(i) // Uncaught ReferenceError: c is not defined
// 若是使用var聲明,則在這裏輸出的就是10
複製代碼
let
實際上爲JavaScript
新增了塊級做用域
const
也是 ES6
新增的聲明變量的方式,const
聲明一個只讀的常量。一旦聲明,常量的值就不能改變
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' // 正常執行
f = {name: 'World'} // 報錯
複製代碼
因此,使用 const
聲明的變量具備如下特色:
const
一旦聲明變量,就必須當即初始化,不能留到之後賦值const
實際上保證的,並非變量的值不得改動,而是變量指向的那個內存地址不得改動若是真的想將對象凍結,應該使用
Object.freeze
方法
ES6
新增的模塊的概念。
模塊功能主要由兩個命令構成:
export
和import
。export
命令用於規定模塊的對外接口,import
命令用於輸入其餘模塊提供的功能
因此在必定程度上來講,import
也具備聲明變量的功能。只是在使用 import
的時候,具備一些限制
export { first, last }
import { first, last } from './xxx'
first = {} // Syntax Error : 'a' is read-only;
first.name = 'Hello' // 成功執行,可是不建議這樣使用
export default function(){} // a.js
import xxx from 'a.js'
import { New as $ } from './xxx'
複製代碼
特色:
import
命令接受一對大括號,大括號裏面的變量名,必須與被導入模塊對外接口的名稱相同import
命令輸入的變量都是隻讀的,由於它的本質是輸入接口export default
命令,爲模塊指定默認輸出的時候,import
命令能夠爲該匿名函數指定任意名字import
命令具備提高效果,會提高到整個模塊的頭部,首先執行import
命令要使用 as
關鍵字,將輸入的變量重命名本質上,
export default
就是輸出一個叫作default
的變量或方法,而後系統容許你爲它取任意名字
ES6
引入了類的概念,有了 class
這個關鍵字,做爲對象的模板。經過 class
關鍵字,能夠定義類
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
複製代碼
ES6
的class
能夠看做只是一個語法糖,它的絕大部分功能,ES5
均可以作到,類的實質仍是函數對象,類中的方法和對象其實都是掛在對應的函數對象的prototype
屬性下
因此就能夠改寫成下面這種ES5的方式
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function() {
return '(' + this.x + ', ' + this.y + ')';
}
複製代碼
特色:
constructor
函數,若是沒有顯式定義,一個空的 constructor
方法會被默認添加。固然全部函數對象都必須有個主體ES5
經過構造函數生成對象徹底同樣,也是使用 new
命令class B {}
let b = new B();
複製代碼
Class
也可使用表達式的形式定義Class
其實就是一個 function
,可是有一點不一樣,Class
不存在變量提高,也就是說 Class
聲明定義必須在使用以前在瀏覽器環境指的是
window
對象,在Node
指的是global
對象。ES5
之中,頂層對象的屬性與全局變量是等價的
var
命令和function
命令聲明的全局變量,依舊是頂層對象的屬性;另外一方面規定,let
命令、const
命令、class
命令聲明的全局變量,不屬於頂層對象的屬性。也就是說,從ES6
開始,全局變量將逐步與頂層對象的屬性脫鉤
var a = 1;
window.a // 1
let b = 2;
window.b // undefined
複製代碼
在 JavaScript
中還存在着隱式聲明。
a = 1;
console.log(a) // 1
複製代碼
當沒有聲明,直接給變量賦值時,會隱式地給變量聲明,此時這個變量做爲全局變量存在。這個時候就不存在聲明提早的問題了
其實只要咱們理解並掌握了這幾種聲明變量的方式,記住它們的特色,那麼在實際使用的過程中就很容易可以找到最合適的方式去定義
天天學習分享,不按期更新
最後,推薦一波前端學習歷程,這段時間總結的一些面試相關,分享給有須要的小夥伴,歡迎 star
關注 傳送門