块级作用域
- ES5只有
全局作用域和函数作用域,ES6新增了块级作用域。
function f1() {
var n = 5;
if (true) {
var n = 10;
}
console.log(n);
}
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n);
}
{{{{
{let insane = 'Hello World'}
console.log(insane);
}}}};
let命令
- ES6新增了
let命令用来声明变量。但所声明的变量只在let命令所在的代码块内有效。
{
let a = 10;
var b = 1;
}
a
b
- 在使用
let声明迭代变量时,每次迭代循环都会创建一个新的块级作用域,变量仅在当前循环内部可见。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();
var a = [];
for (var i = 0; i < 10; i++) {
(function(j){
a[i] = function(){
console.log(j);
}
})(i);
}
不存在变量提升
var声明的变量存在变量提升,即变量可以在声明前使用,值为undefined。而let命令声明的变量一定要在声明后使用,否则报错。
console.log(foo);
var foo = 2;
console.log(bar);
let bar = 2;
暂时性死区
- 如果区块中存在
let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
if (true) {
tmp = 'abc';
console.log(tmp);
let tmp;
console.log(tmp);
tmp = 123;
console.log(tmp);
}
暂时性死区意味着typeof不再是一个百分之百安全的操作。
typeof x;
let x;
typeof xxxx;
不允许重复声明
function func() {
let a = 10;
var a = 1;
}
function func() {
let a = 10;
let a = 1;
}
const命令
const声明一个只读常量,只在声明所在的块级作用域内有效。一旦声明就必须立即初始化,且常量的值不能改变。
const PI = 3.1415;
PI
PI = 3;
const foo;
不存在变量提升
暂时性死区
不允许重复声明
常量的本质
- 并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
const a = 1;
a = 2;
const obj = {};
obj.a = 1;
obj = [];
ES6声明变量的6种方法
- ES5中的
var 、function,ES6中的let、const、import、class。
顶层对象的属性
- ES6 为了保持兼容性,
var命令和function命令声明的全局变量,依旧是顶层对象window的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。
var a = 10;
function test(){}
console.log(window.a);
console.log(window.test)
let b = 20;
console.log(window.b);
globalThis对象
- ES2020在语言标准的层面,引入
globalThis作为顶层对象。也就是说,任何环境下,globalThis都是存在的,都可以从它拿到顶层对象,指向全局环境下的this。