ES6-5【隐式转换、函数参数解构、解构本质、()用法】

一、解构本质

解构赋值本质就是给变量赋值,赋值的方式就是模式匹配

二、()用法

解构赋值对象如果不let声明,JS就认为它是一个语法块(块级作用域)

let a;
{ a } = { a: 1 };
console.log(a) // 报错

解决方法:用括号包裹,变成表达式

let a;
({ a } = { a: 1 });
console.log(a) // 1

只有这种情况加括号不会报错,取余情况均会报错


当用 let、var 的方式来声明,只要加了括号就报错

加了括号就是表达式,语法不通过,所以报错

let [(a)] = [1];
let {(a):b} = {};
let ({a:(b)}) = {};
let ({a:b}) = {}; // 全报错

函数的形参也不能加括号

因为上一节课已经得出结论:函数的形参也是用let声明的,所以加上括号就会报错

function foo(([z])) {
    return z;
}
console.log(foo([1])); //报错

模式匹配必须l模式一样才能匹配

[b] = [3];
console.log(b); // 3

([b]) = [3];
console.log(b); // 报错 匹配规则不对,所以匹配不成功

({a: (b) = {}})
console.log(b); // {}  没有匹配 JS认为{a: (b) = {}}是一个对象,a是属性,b是属性值 默认值为{}

var a = {};
[(a.b)] = [3]; // 以数组的匹配模式 给a对象的b属性赋值3
console.log(b); // 报错 匹配了 但必须通过a.b访问

let is not defined

一般情况下就是因为 let = (…) 导致的错误,let不能声明表达式

三、解构妙用

模式匹配可以给对象的属性赋值

let a1 = [1, 2, 3], obj2 = {};

[obj2.a, obj2.b, obj2.c] = a1;

console.log(obj2.a, obj2.b, obj2.c); // 1,2,3

计算属性解构

数组是特殊的对象,也支持对象的匹配规则

let arr = [1, 2, 3];
let { 0: first, [arr.length - 1]: last } = arr;
console.log(first, last); // 1,3

字符串拼接属性

let a = 'x', b = 'y', obj = {};
// { a: obj[a + b] } = { a: 2 } 这里不通过的原因是它认为{}是一个块级作用域,所以要把它变成表达式,这样才能解构
({ a: obj[a + b] } = { a: 2 });
console.log(obj.xy); // 2

交换值

let a = 10, b = 20;

[b, a] = [a, b]
console.log(a, b); // 20 10

模式匹配允许匹配同源属性(同一个源属性)

只要匹配的源属性存在,就可以写多个相同的属性

但是变量不能相同,因为这样就重复声明了

let { a: x, a: y } = { a: 1 };
console.log(x, y); // 1 1

let { a: x, a: x } = { a: 1 };
console.log(x, x); // 报错,重复声明

解构的默认参数

在解构中使用对象或是数组的时候,慎用(可读性非常差)

var x = 200,
    y = 300,
    z = 100;
var obj1 = { x: { y: 42 }, z: { y: z } };

({ y: x = { y: y } } = obj1); // x = {y: 300}
({ z: y = { y: z } } = obj1); // y = {y: 100}
({ x: z = { y: x } } = obj1); // z = {y: 42}

console.log(x, y, z); // { y: 300 } { y: 100 } { y: 42 }

注意

({ x = 10 } = {}); // x => x:x=10
({ y } = { y: 10 }); // y => y:y
console.log(x, y); // 10 10

四、函数参数解构

数组解构

function test([x, y]) {
    console.log(x, y);
}
test([1, 2]); // 1, 2
test([1]); // 1 undefined
test([]); // undefined undefined

对象解构

function test({ x, y }) {
    console.log(x, y);
}
test({ x: 1, y: 2 }); // 1, 2
test({ x: 1 }); // 1 undefined
test({}); // undefined undefined

默认参数

注意除了函数有默认值,解构参数也有默认值

function foo({ x = 10 } = {}, { y } = { y: 10 }) {
    console.log(x, y);
}

foo() // 10 10
foo({},{}) // 10 undefined
foo({x:2},{y:3}) // 2 3

五、解构隐式转换

布尔值、number、boolean都会进行隐式转换

字符串转为类数组

const [a, b, c, d, e] = 'hello'; // 这里将字符串隐式转换成了类数组
console.log(a, b, c, d, e) // h e l l o

// 验证
let { length: len } = 'hello';
console.log(len); // 5

数值转换相应的包装类

let { toString: s } = 123;
console.log(s); // [Function: toString]

// 验证
console.log(s === Number.prototype.toString); // true

布尔值转换相应的包装类

let { toString: s } = false;
console.log(s); // [Function: toString]

// 验证
console.log(s === Boolean.prototype.toString); // true

undefined和null不能进行隐式转换

let { prop } = undefined;
console.log(prop); // 报错

let { prop } = null;
console.log(prop); // 报错

包装类其实就是JS底层经过加工的对象,方便隐式转换

六、书写规范

建议使用缩进增强代码可读性

let person = {
    name: 'zs',
    ageZhang: 50,
    son: {
        name: 'ls',
        ageLi: 30,
        son: {
            name: 'ww',
            ageWang: 18,
            son: {
                name: 'zl',
                ageZhao: 0
            }
        }
    }
}

// 不要这样写
let { son: { son: { son: { ageZhao }, ageWang }, ageLi }, ageZhang } = person;
console.log(ageZhao, ageWang, ageLi, ageZhang);

// 规范写法
let {
    son: {
        son: {
            son: {
                ageZhao
            },
            ageWang
        },
        ageLi
    },
    ageZhang
} = person;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ES6-ES12是JavaScript的不同版本,每个版本都引入了新的特性和改进。以下是一些ES6到ES12的新特性的示例: ES6(2015年): 1. 箭头函数:简化了函数的语法。 2. 模板字面量:使用反引号(`)来创建多行字符串和插入变量。 3. 解构赋值:从对象或数组中提取值并赋给变量。 4. let和const:引入块级作用域的变量声明方。 5. Promise:处理异步操作的更强大的方ES7(2016年): 1. Array.prototype.includes():判断数组是否包含某个元素。 2. 指数操作符:使用双星号(**)进行指数运算。 ES8(2017年): 1. async/await:更简洁地处理异步操作。 2. Object.values()和Object.entries():从对象中提取值或键值对。 ES9(2018年): 1. Rest/Spread属性:通过...语法来处理函数参数和对象字面量。 2. Promise.prototype.finally():在Promise结束时执行操作。 ES10(2019年): 1. Array.prototype.flat()和Array.prototype.flatMap():用于处理嵌套数组的方法。 2. Object.fromEntries():将键值对列表转换为对象。 ES11(2020年): 1. 可选链操作符(Optional chaining):简化了访问深层嵌套属性的方。 2. Nullish coalescing操作符:提供了一种默认值的设定方ES12(2021年): 1. Promise.any():在多个Promise中返回最快决的结果。 2. Logical Assignment Operators:提供了逻辑运算符与赋值的结合方。 当然,以上仅是一些主要的新特性,ES6-ES12还有其他许多有用的功能和语法改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值