# ES6之变量声明
# var的用法及注意点
var声明在函数内属于局部变量,仅在函数的作用域内可访问。在函数之外则属于全局变量,顾名思义,var声明的变量影响至全局(比如A module、b module被引入一个文件,倘若AB声明了同名变量,则按照先后顺序,前者声明将被后者覆盖。)。除此之外,var还有几个特性:
具有变量提升,例如声明a,js允许var声明没有初始值,默认为undefined。
var a = 2; //实际上是 var a; // undefined a=2;
function foo(){ let name = "李斯特"; // var dd; //变量提升 if(name == "奥尔莱"){ var dd = 4; } console.log("dd",dd); // dd undeinfed }
可以重复声明
var c = 1; var c = 2; var c = 3; console.log(c) // 3
js设计上的缺陷,顶层对象属性会被var声明所覆盖
// 浏览器的顶层对象是window,Node的是global window.a = 2; var a = 3; console.log(a); // 3;
# let的用法及注意点
let和var一样用来声明变量,其有以下几个不同点:
- 不允许重复声明
- 声明时需要确切的值。
- 不存在变量提升
console.log(foo);
var foo = "a";
//var实际上的声明是
var foo = undeinfed;
console.log(foo);
foo = "a";
//--------------------
//而let不存在变量提升
console.log(bar); // 报错ReferenceError
let bar = 2;
作用域为当前代码段
var outer = 123; console.log(inner); // inner is undefined function test(){ console.log(outer); // 123 }
在for循环中有特别之处,for中的作用域,与代码块里的作用域是互相独立的。
for(let i = 0 ; i< 3;i++) { let i = 'abc'; console.log(i); } // abc // abc // abc
暂时性死区
/** * 用let声明一个其作用域外已声明过的变量 * 则作用域内的变量,不再受到外界的影响 */ var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
WARNING
ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
# const的用法及注意点
const的用法及注意点和let相似,异同点如下:
与let拥有相同作用域。
声明时需要确切的值。
const常量并不是绝对保证变量无法改动。而是保证找个变量指向的内存地址所保存的数据无法改动。但如果是引用类型,则涉及到堆内存,那么堆内存中的数据将可以改动。
const a = []; a.push('Hello'); // 可执行 a.length = 0; // 可执行 a = ['Dave']; // 报错
# ES6中有几种声明方式?
一共有6种,分别是var、function、let、const、class、import。
# 全局变量
JS中除了有var这样声明全局变量,还有顶层对象window,如果给window添加属性,则会和全局变量混淆,这是JS中设计失误的地方。
window.a = 1;
a // 1
a = 2;
window.a // 2
但好在let可以解决var污染顶层对象属性这一情况
var a = 1;
// 如果在 Node 的 REPL 环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
window.a // 1
let b = 1;
window.b // undefined
TIP
并非所有环境下(Node、Web Worker)都拥有window,因此ES2020中引入globalThis作为顶层对象,以保证适配各种环境。