做者:Valentino翻譯:瘋狂的技術宅javascript
https://www.valentinog.com/bl...前端
未經容許嚴禁轉載java
var
語句用來在 JavaScript 中聲明一個變量,該變量遵照如下規則:程序員
window
上以相同的名稱建立一個全局屬性。當出如今全局做用域內時,var
建立一個全局變量。另外它還會在 window
上建立一個具備相同名稱的 全局屬性:面試
var city = "Florence"; console.log(window.city); // "Florence"
當在函數內部聲明時,變量的做用域爲該函數:segmentfault
var city = "Florence"; function bubble() { var city = "Siena"; console.log(city); } bubble(); // "Siena" console.log(city); // "Florence"
var
聲明會被提高:服務器
function bubble() { city = "Siena"; console.log(city); var city; // hoists } bubble(); // "Siena"
在沒有任何聲明的狀況下所分配的變量(不管是 var
,let
仍是 const
)在默認狀況下會成爲全局變量:微信
function bubble() { city = "Siena"; console.log(window.city); } bubble(); // "Siena"
爲了消除這種行爲,須要使用嚴格模式:多線程
"use strict"; function bubble() { city = "Siena"; console.log(window.city); } bubble(); // ReferenceError: assignment to undeclared variable city
任何用 var
聲明的變量均可以在之後進行從新分配或從新聲明。從新聲明的例子:框架
function bubble() { var city = "Florence"; var city = "Siena"; console.log(city); } bubble(); // "Siena"
從新分配的例子:
function bubble() { var city = "Siena"; city = "Florence"; console.log(city); } bubble(); // "Florence"
let
語句在 JavaScript 中聲明一個變量,該變量遵照如下規則:
window
上建立任何全局屬性。用 let
聲明的變量不會在 window
上建立任何全局屬性:
let city = "Florence"; console.log(window.city); // undefined
當在函數內部聲明時,變量的做用域爲該函數:
let city = "Florence"; function bubble() { let city = "Siena"; console.log(city); } bubble(); // "Siena" console.log(city); // "Florence"
當在塊中聲明時,變量的做用域爲該塊。如下是在塊中使用的例子:
let city = "Florence"; { let city = "Siena"; console.log(city); // "Siena"; } console.log(city); // "Florence"
一個帶有 if
塊的例子:
let city = "Florence"; if (true) { let city = "Siena"; console.log(city); // "Siena"; } console.log(city); // "Florence"
相反,var
並不受到塊的限制:
var city = "Florence"; { var city = "Siena"; console.log(city); // "Siena"; } console.log(window.city); // "Siena"
let
聲明可能會被提高,可是會產生暫存死區:
function bubble() { city = "Siena"; console.log(city); // TDZ let city; } bubble(); // ReferenceError: can't access lexical declaration 'city' before initialization
暫存死區可防止在初始化以前訪問 let
聲明。另一個例子:
function bubble() { console.log(city); // TDZ let city = "Siena"; } bubble(); // ReferenceError: can't access lexical declaration 'city' before initialization
能夠看到兩個例子中產生的異常都是同樣的:證實了「暫存死區」的出現。
任何用 let
聲明的變量都不能從新聲明。從新聲明引起異常的例子:
function bubble() { let city = "Siena"; let city = "Florence"; console.log(city); } bubble(); // SyntaxError: redeclaration of let city
這是一個有效的從新分配的例子:
function bubble() { let city = "Siena"; city = "Florence"; console.log(city); } bubble(); // "Florence"
const
語句用來在 JavaScript 中聲明一個變量,該變量遵照如下規則:
window
上建立任何全局屬性。用 const 聲明的變量不會在 window
上建立任何全局屬性:
const city = "Florence"; console.log(window.city); // undefined
當在函數內部聲明時,變量的做用域爲該函數:
const city = "Florence"; function bubble() { const city = "Siena"; console.log(city); } bubble(); // "Siena" console.log(city); // "Florence"
當在塊中聲明時,變量的做用域爲該塊。塊語句 {}
的例子:
const city = "Florence"; { const city = "Siena"; console.log(city); // "Siena"; } console.log(city); // "Florence"
在 if
塊中的例子:
const city = "Florence"; if (true) { const city = "Siena"; console.log(city); // "Siena"; } console.log(city); // "Florence"
const
聲明可能會被提高,可是會進入暫存死區:
function bubble() { console.log(city); const city = "Siena"; } bubble(); // ReferenceError: can't access lexical declaration 'city' before initialization
用 const
聲明的任何變量都不能從新聲明,也不能從新分配。 一個在從新聲明時拋出異常的例子:
function bubble() { const city = "Siena"; const city = "Florence"; console.log(city); } bubble(); // SyntaxError: redeclaration of const city
從新分配的例子示例:
function bubble() { const city = "Siena"; city = "Florence"; console.log(city); } bubble(); // TypeError: invalid assignment to const 'city'
塊做用域 | 暫存死區 | 建立全局屬性 | 可從新分配 | 可從新聲明 | |
---|---|---|---|---|---|
var |
❌ | ❌ | ✅ | ✅ | ✅ |
let |
✅ | ✅ | ❌ | ✅ | ❌ |
const |
✅ | ✅ | ❌ | ❌ | ❌ |