let
let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
什么叫代码块?简单地说:使用{}括起来的代码被称为代码块。比如:if、for、try…catch这些都是代码块
var a = 20
if (a % 2 === 0) {
let b = 5
}
console.log(b) // ReferenceError: b is not defined.
我们可以看到,在if块里用let定义的b变量在这个块级外面是不可使用的。
let还有一个特点就是没有变量提升
console.log(a) // undefined
console.log(b) // ReferenceError: b is not defined.
var a = 10
let b = 20
暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var a = 20
if (a % 2 === 0) {
console.log(a) // ReferenceError: Cannot access 'a' before initialization
let a = 10
}
面代码中,存在全局变量a,但是块级作用域内let又声明了一个局部变量a,导致后者绑定这个块级作用域,所以在let声明变量前,打印a会报错。这种情况被称为暂时性死区
const
const声明一个只读的常量。一旦声明,常量的值就不能改变
const a = 10
a++ // TypeError: Assignment to constant variable.
const一旦声明变量,就必须立即初始化,不能留到以后赋值
const a // SyntaxError: Missing initializer in const declaration
const命令声明的常量也是不提升
console.log(a) // ReferenceError: Cannot access 'a' before initialization
const a = 10
const命令同样存在暂时性死区
const a = 20
if (a % 2 === 0) {
console.log(a) // ReferenceError: Cannot access 'a' before initialization
const a = 10
}
但是,我们来看看下面的代码
const arr = [ 2, 5, 6]
arr.push(7)
console.log(arr) // [ 2, 5, 6, 7 ]
arr = [ 2, 5, 6, 7 ] // TypeError: Assignment to constant variable.
const obj = {
key1: 'value1',
key2: 'value2'
}
obj.key3 = 'value2'
console.log(obj) // { key1: 'value1', key2: 'value2', key3: 'value3' }
obj = { key1: 'value1', key2: 'value2', key3: 'value3' } // TypeError: Assignment to constant variable.
我们可以看到,用const申明的数组和对象是可以被修改的,但是不能被重新赋值,这说明了什么问题?
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了
扩展运算符
扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为一系列用逗号分隔的值。
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
也可以拷贝数组
var arr = [3, 4, 5]
var arr1 = [...arr]
甚至在拷贝的同时追加元素
var arr = [3, 4, 5]
var arr1 = [2, ...arr, 6, 7, 8]
在ES2018的标准里,扩展也可以用于对象
var obj = {
key1: 'value1',
key2: 'value2'
}
var obj2 = {
...obj,
key3: 'value3'
}
模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量
// 普通字符串
`In JavaScript '\n' is a line-feed.`
// 多行字符串
`In JavaScript this is
not legal.`
console.log(`string text line 1
string text line 2`);
// 字符串中嵌入变量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
函数默认参数
ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。
function log(x, y) {
y = y === undefined ? 'World' : y
console.log(x, y)
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
ES6允许在定义参数的时候给默认值
function log(x, y = 'World') {
console.log(x, y)
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
代码不是万能的,但不写代码是万万不能的
2020/05/12 Www记