let 命令
基本用法
类似var
,但是声明的变量是局部变量
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
特性
- 不存在变量提升
变量可以在声明之前使用
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
- 暂时性死区
在代码块内,使用let命令声明变量之前,该变量都是不可用的
例子:
//声明前使用let声明的变量都会报错
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
//y还没声明
function bar(x = y, y = 2) {
return [x, y];
}
bar(); // 报错
// 不报错
var x = x;
// 报错
let x = x;
// ReferenceError: x is not defined
块级作用域
块级作用域的作用
- 外层作用域无法获取到内层作用域
- 避免函数作用域覆盖了全局作用域
- 避免循环中的变量泄露为全局变量
形式
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
外层代码块不受内层代码块影响
块级作用域与函数声明
- 允许在块级作用域内声明函数
- 函数声明类似于var,即会提升到全局作用域或函数作用域的头部
- 函数声明还会提升到所在的块级作用域的头部
const 命令
基本用法
const
声明一个只读的常量。一旦声明,常量的值就不能改变
const PI = 3.1415;
PI // 3.1415
PI = 3; // 会报错
特性
- 只在声明所在的块级作用域内有效
- 不存在变量提升
本质
const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心
顶层对象的属性
在浏览器环境中指的是window
对象,es5中顶层对象与全局变量相等
window.a = 1;
a // 1
a = 2;
window.a // 2
es6 中let
命令 const
命令声明的变量不属于顶层对象的属性
var a = 1;
window.a // 1
let b = 1;
window.b // undefined
const c = 1;
window.c // undefined
global 对象
ES5 的顶层对象(但是在不同地方的实现不一样)
取顶层对象
// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
// 方法二
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};