暂时性死区,TDZ(Temporal Dead Zone)
js
var x = 1
{
let x = x//此处声明了x,但是没有对x赋值,相当于在赋值之前引用x,所以会造成报错
console.log(x)//报错x is not defined,暂时性死区,不能拿到父级作用域中的x
}
参数默认值
falsy(虚值):通过Boolean转化,转为假的值叫虚值
let x = 1
funciton foo(y = x){
let x = 2 //在这之前会有暂时性死区
console.log(y);// 执行后打印1,访问外层作用域的1
}
<--------------------->
let x = 1;
function foo(x = 2){
let x = 2;//此处会报错,x已经被声明过了,给默认值的时候相当于声明了一个x = 2
console.log(x);
}
<--------------------->
let x = 1;
function foo(x = x){
let x = 2;
console.log(x);
}
foo();//报错,由let x = 2引起
<--------------------->
let x = 1;
function foo(x = x){
console.log(x);//x is not defined
}
foo();//报错,参数也有作用域
foo(11)//给了值就打印11
<--------------------->
var w = 1, z = 2;
function foo(x = w + 1, y = x + 1;z = z +1){
console.log(x,y,z);//报错,z is not defined,此时x = w + 1,w找的是外层作用域的w, y = x + 1;此处的x找的是,前面x = w + 1中的x,到此处不会报错,接着z = z + 1,此处,z + 1中找的z是等号前面的z,即使外层有z,也不会找,因此会在此处报错
}
foo()
// 如果这样打印
var w = 1, y = 6;
function foo(x = w + 1, y = x + 1){
console.log(x,y);// 打印2,3,从而可以看出y取值并不是是取的外层的x
}
foo()
函数的参数为表达式时,函数的执行
函数的参数为表达式的情况下,此时的加载方式,是惰性求值的方式
let a = 99
function foo(b = a + 1){ //此时参数传的值都是进行重新计算的一个值
console.log(b)
}
foo()//100
a = 100
foo()//101
解构赋值
ES6新增的一个语法特征
数组解构
没有解构赋值之前我们定义三个变量会这样写
js
let a = 1,
b = 2,
c = 3;
```
有解构之后可以这么写
解构通过模式匹配的方式或者叫结构化赋值(匹配相同的解构进行赋值)
```js
let [a, b, c] = [1, 2, 3]
解构失败,变量如果在右边没有对应的值,就会用undefined填充;不完全解构,就是值多了
解构默认值
js
let [a = 6] = [1]
console.log(a)//1
let [a = 6] = []
console.log(a)//6
let [a, b=2] = [1]
console.log(a,b)//a:1,b:2,a被赋值,b使用默认值
//除了undefined会取默认值,其他的都会取传入的值
let [a, b = 2] = [1, undefined]
console.log(a, b)//1, 2
let [a, b = 2] = [1, null]
console.log(a, b)//1, 2
// 默认值也可以给函数,模式匹配有值先取值,没值再去找默认值,从而执行这个函数
function test(){
console.log(1)
}
let [x = test()] = [1]
console.log(x)//可以正常打印1
let [x = 1, y = x] = []
console.log(x,y)//1,1
let [x = 1, y = x] = [2]
console.log(x,y)//2,2
let [x = 1, y = x] = [1, 2]
console.log(x,y)//1,2,有值取值,没值访问默认值
let [x = y, y = 1] = []
console.log(x,y)//报错y is not defined,在定义y之前使用了y
对象解构
js
ES5定义对象的几种方式
let obj = {}
let obj1 = new Object()
let obj2 = Object.create(null)
var name = 'zhangsan'
var age = 12
let person = {
name,//属性名和变量名一致可以省略,直接写属性名
age,
sex: 'male',
eat(){
//如果对象属性是方法 ES6可以这样写
console.log('apple')
}
}
// 属性名拼接
let fName = 'xiao'
let sName = 'ming'
let name = 'xiaoming'
let person1 = {
[fName + sName]: name
}
结构完全一样的两个对象可以通过解构进行变量赋值
js
let {a: a, b: b,c: c} = {a: 1, b: 2, c: 3}
不完全解构和解构失败
// 不完全解构,值比变量多
let {a = 1, b, c } = {a: 1, b: 2, c: 3},e: 4,f:5}
// 解构失败,变量比值多,没有解构的就会赋值为undefined
let {a = 1, b, c,e } = {a: 1, b: 2, c: 3}
数组的解构会存在顺序问题,而对象的解构不会有顺序问题,它是根据对应的属性名进行解构的
如何取出wangwu?
js
var person = {
name: 'zhangsan',
age: 50,
son:{
name: 'lisi',
age: 30,
son:{
name: 'wangwu',
age: 12
}
}
}
let {son:{son:son1} = person
console.log(son1)//就是王五这个人