作者:Valentino
翻译:疯狂的技术宅
https://www.valentinog.com/bl…
未经容许严禁转载
var
var
语句用来在 JavaScript 中申明一个变量,该变量恪守以下规定:
- 作用域范畴是函数作用域或全局作用域的。
- 不受暂存死区(TDZ)的限度。
- 它会在
window
上以雷同的名称创立一个全局属性。 - 是 可调配的。
- 是 可申明的。
函数作用域和全局作用域
当呈现在全局作用域内时,var
创立一个全局变量。另外它还会在 window
上创立一个具备雷同名称的 全局属性:
var city = "Florence";
console.log(window.city); // "Florence"
当在函数外部申明时,变量的作用域为该函数:
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
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
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 |
✅ | ✅ | ❌ | ❌ | ❌ |
本文首发微信公众号:前端先锋
欢送扫描二维码关注公众号,每天都给你推送陈腐的前端技术文章
欢送持续浏览本专栏其它高赞文章:
- 深刻了解 Shadow DOM v1
- 一步步教你用 WebVR 实现虚拟现实游戏
- 13 个帮你进步开发效率的古代 CSS 框架
- 疾速上手 BootstrapVue
- JavaScript 引擎是如何工作的?从调用栈到 Promise 你须要晓得的所有
- WebSocket 实战:在 Node 和 React 之间进行实时通信
- 对于 Git 的 20 个面试题
- 深刻解析 Node.js 的 console.log
- Node.js 到底是什么?
- 30 分钟用 Node.js 构建一个 API 服务器
- Javascript 的对象拷贝
- 程序员 30 岁前月薪达不到 30K,该何去何从
- 14 个最好的 JavaScript 数据可视化库
- 8 个给前端的顶级 VS Code 扩大插件
- Node.js 多线程齐全指南
- 把 HTML 转成 PDF 的 4 个计划及实现
- 更多文章 …