ES6-4【解构赋值、函数默认值、数组解构、对象解构】

一、函数默认值

(1)暂时性死区

暂时性死区 TDZ(Temporal Dead Zone)

var x = 1;
{
    let x = x; //报错
    log(x) 
} 

这里的x取的是let产生的块级作用域中的x,由于暂时性死区问题,let 声明的x并没有赋值,所以报错

侧面印证了let声明的变量,访问不到父级作用域

(2)参数默认值

ES写法

function foo(x,y){
    x = x || 1;
    y = y || 2;
    console.log(x+y);
}
foo(); //3
foo(5,6); //11
foo(5); //7
foo(null,6);//7
foo(0,5);//6 这里就会出问题这是falsy(虚值Boolean为假的值),我赋值的是0

ES5写法

//es5解决方案
function foo(x, y) {
    var a = typeof (arguments[0]) !== 'undefined' ? arguments[0] : 1;
    var b = typeof (arguments[1]) !== 'undefined' ? arguments[1] : 2;
    console.log(a + b);
}
foo(); //3
foo(5, 6); //11
foo(5); //7
foo(null, 6);//6 null转换成了0
foo(0, 5);//5

虚值:在通过boolean转化的时候可以转化为假的值就是falsy(虚值)

ES6写法

function foo(x = 1, y = 2) {
    console.log(x + y);
}

foo(); //3
foo(5, 6); //11
foo(5); //7
foo(null, 6); //6
foo(0, 5) //5

作用域深入

let x =1;
function foo(y = x){
    let x =2;
    console.log(y);
}
foo();//输出1,这里可以打印出1的原因是let声明的是y产生了块级作用域,所有y访问不到父级作用域的变量,但x可以拿到
 
let x =1;
function foo(x = 2){ // ()里的x是let声明的,且与{}的作用域是同级的,x重复声明所以报错
    let x = 2;
    console.log(x);
}
foo();//报错
 
let x = 1;
function foo(x = x){ // ()里的x是let声明的,且与{}的作用域是同级的,x重复声明所以报错
	let x = 2;
	console.log(x);
}
foo(); //报错

let x = 1;
function foo(x = x) { // 暂时性死区(包括let之前与当前),x还未声明
    console.log(x);
}
foo(); //报错 

let x = 1;
function foo(x = x) { // 传了实参,默认参数就不会再赋值,所以不报错
    console.log(x);
}
foo(1); //输出1

默认值运算

var w = 1, z = 2;
function foo(x = w + 1, y = x + 1, z = z + 1) { // 暂时性死区,z还未声明
    console.log(x, y, z)
}
foo(); // 报错

var w = 1, z = 2;
function foo(x = w + 1, y = x + 1) {
    console.log(x, y)
}
foo(); // 2、3

惰性求值
每一次都要重新计算表达式的值

// 函数的默认参数为表达式的情况下的加载方式是一个惰性求值的方式,即不会缓存默认值,每次调用都会重新计算
let a = 99;
function foo(b = a + 1){
    console.log(b);
}
foo(); 
a = 100;
foo();//输出100,101 惰性求值

二、解构赋值(数组)

模式匹配(结构化复制)
两边的结构要一致

let [a, b, c] = [1, 2, 3]
console.log(a, b, c) // 1 2 3

let [d, [e], [f]] = [1, [2], [3]]
console.log(d, e, f) // 1 2 3

解构失败
变量多了,值少了

let [a, [b,c], [d,e]] = [1, [2,3], [,]]
console.log(a,b,c,d,e) // 1 2 3 undefined undefined

不完全解构
值多了,变量少了

let [a, [,], [d,e]] = [1, [2,3], [4,5]]
console.log(a,b,c,d,e) // 1 4 5

解构默认值

let [a = 6] = [1];
console.log(a); // 1

let [a = 6] = [];
console.log(a); // 2

let [a, b = 2] = [1];
console.log(a, b); // 1 2

let [a, b = 2] = [1, undefined]; // 除了undefined取默认值以外取的所有值都是原本的值,JS引擎会认为是空
console.log(a, b); // 1 2

let [a, b = 2] = [1, null];
console.log(a, b); // 1 null

function test() {
    console.log(10);
}
let [x = test()] = [1];
console.log(x); // 1

function test() { // 函数默认返回undefined
    console.log(10);
}
let [x = test()] = [];
console.log(x); // undefined

let [x = 1, y = x] = [];
console.log(x, y) // 1 1

let x = 5;
let [x = 1, y = x] = []; // 这个不存在块级作用域,这个x已经被定义,重复声明报错
console.log(x, y) // 报错

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] = []; // 暂时性死区,y还未声明
console.log(x, y); // 报错

三、解构赋值(对象)

属性和方法的简写

var _name = 'zhangsan';
var age = 18
var person = {
    _name, 
    age,
    sex: 'male',
    eat() {console.log(1)}
}
console.log(person) // { _name: 'zhangsan', age: 18, sex: 'male', eat: [Function: eat] }

属性拼接

let firstName = 'ai';
let secondName = 'xiaoye';
let _name = 'ai xiaoye';
let person = {
    [firstName + secondName]: _name,
    // [firstName + 'xiaoye']: _name,
    // ['ai' + 'xiaoye']: _name,
}
console.log(person); // { aixiaoye: 'ai xiaoye' }

对象的解构
结构一致,属性名称一致

let { a: a, b: b, c: c } = { a: 1, b: 2, c: 3 };
// 简写
let { a, b, c } = { a: 1, b: 2, c: 3 };
console.log(a, b, c); // 1 2 3

不完全解构
值多了,变量少了

let { a = 2, b, c } = { a: 1, b: 2, c: 3, e: 4, f: 5 };
console.log(a, b, c); // 1 2 3

// 默认值
let { a = 2, b, c } = { b: 2, c: 3, e: 4, f: 5 };
console.log(a, b, c); // 2 2 3

解构失败
变量多了,值少了

let { a = 2, b, c, d, e, f, g, h } = { b: 2, c: 3, e: 4, f: 5 };
console.log(a, b, c, d, e, f, g, h); // 2 2 3 undefined 4 5 undefined undefined

小问题

// 数组的结构存在顺序的问题
// let [d, [e], [f]] = [1, [2], [3]];
// console.log(d,e,f) // 1 2 3
let [d, [e], [f]] = [2, [1], [3]];
console.log(d,e,f) // 2 1 3

// 对象的结构不存在顺序的问题
// let { a, b, c } = { a: 1, b: 2, c: 3 };
// console.log(a, b, c) // 1 2 3
let { a, b, c } = { c: 3, b: 2, a: 1 };
console.log(a, b, c) // 1 2 3

现象

const {son} = person;

我们经常看到这样的解构,其实就是拿取person里的son属性,然后与取出来的变量同名

在这里插入图片描述

三、实战

实战1:拿到JSON里面的course数据

// 思路:首先结构要一致,然后用一个变量来接收
var data = [{ "id": 1, "course": "前端开发", "classes": 100, "teacher": "小野" }, { "id": 2, "course": "后端开发", "classes": 120, "teacher": "小夏" }, { "id": 1, "course": "全栈开发", "classes": 200, "teacher": "哈默" }];
let [{ course: course1 }, { course: course2 }] = data;
console.log(course1, course2); // 前端开发 后端开发

实战2:取到wangwu儿子

var pserson = {
    name: "张三",
    age: 50,
    son: {
        name: 'lisi',
        age: 30,
        son: {
            _name: 'wangwu',
            age: 12
        }
    }
}

let { son: { son } } = pserson;
console.log(son) // { _name: 'wangwu', age: 12 }
let { son: { son: son1 } } = pserson;
console.log(son1) // { _name: 'wangwu', age: 12 }

这里其实就是多层解构,把第一层解构的结果拿到然后以:{属性}或:{属性:变量名}的形式再继续解构

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值