JavaScript聲明變量詳解

前言

若是文章中有出現紕漏、錯誤之處,還請看到的小夥伴多多指教,先行謝過前端

ES5階段,JavaScript 使用 varfunction 來聲明變量, ES6 中又添加了letconstimportClass 這幾種聲明變量的方式。那麼,他們各自都有什麼樣的特色呢?git

下面,就讓咱們一塊兒去探究一下吧es6

如下↓github

變量就是存儲信息的容器。 ECMAScript 的變量是鬆散類型的,所謂鬆散類型就是能夠用來保存任何類型的數據

var 聲明

一直以來,咱們都是使用var關鍵字來聲明變量web

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
  • 變量能夠重複定義,且能夠修改值
  • 變量聲明語句從自動提高到所在做用域的頂端
  • 函數內重複定義對函數外無影響(局部變量)
  • 函數內從新賦值對函數外有影響

function 關鍵字聲明

在ES5中,除了使用var聲明變量,咱們也可使用 function 關鍵字聲明變量瀏覽器

f();
function f() {console.log(1)}
var f;

console.log(f) // function f

特色:函數

  • 使用 function 聲明的是函數對象,也存在聲明提高
  • 函數聲明要優於變量聲明

let聲明

因爲 ES5 中使用 var 聲明變量存在着一些很讓人迷惑的特性(好比變量提高,重複定義等),ES6 中新增 let 命令,用來聲明變量。它的用法相似於 var ,可是所聲明的變量,只在 let 命令所在的代碼塊內有效學習

{
    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 聲明變量的特色:this

  • 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聲明

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 方法

import 聲明

ES6 新增的模塊的概念。

模塊功能主要由兩個命令構成: exportimportexport 命令用於規定模塊的對外接口, 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 的變量或方法,而後系統容許你爲它取任意名字

class 聲明

ES6 引入了類的概念,有了 class 這個關鍵字,做爲對象的模板。經過 class 關鍵字,能夠定義類

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
ES6class 能夠看做只是一個語法糖,它的絕大部分功能, 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 關注 傳送門

參考文檔

ECMAScript 6入門

ES6變量聲明

相關文章
相關標籤/搜索