ES6-4/5 解构赋值、函数默认值、数组解构、对象解构

本文详细介绍了ES6中的解构赋值,包括数组解构、对象解构以及函数默认值的用法和注意事项。解构赋值允许我们方便地从数组或对象中提取值,并提供了默认值功能。此外,还探讨了解构的本质,隐式转换,以及对函数length属性的影响。同时,文章强调了函数默认值与作用域的关系,以及在实际项目中的应用。
摘要由CSDN通过智能技术生成

在这里插入图片描述

ES-4 解构赋值、函数默认值、数组解构、对象解构
ES-5 隐式转换、函数参数解构、解构本质、()用法

一 解构赋值

1 虚值

  • 含义:在Boolean转换结果为假的值falsy

2 函数默认值

ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。(默认值如果是函数,当非undefined的情况,函数不会执行,只有在用到的时候,才会求值。)

// es5写法
function foo(x, y) {
    // x = x || 1;
    // y = y || 2;
    // 以上写法,遇0出bug

    // 计算类型的,要取得正确结果,要考虑0的情况,应如下
    if (x !== 0) {
        x = x || 1;
    }
    if (y !== 0) {
        y = y || 1;
    }
    console.log(x + y);
}

以上计算,更人性化的写法应当是将null也转为0

// es6写法 能计算正确结果
function foo(x = 1, y = 2) {
    console.log(x + y)
}
// 转译es5
"use strict";

function foo() {
  var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
  var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
  console.log(x + y);
}
// null的时候,涉及到隐式类型转化Number(null)为0
let x = 1;
function foo(x = 2) {
    let x = 2; // 报错
    // Identifier 'x' has already been declared.
    console.log(x)
}
foo()
let x = 1;
function foo(y = x) {
    console.log(y) // 1
}
foo()

不要和for循环的父子级作用域搞混了,函数形参和函数体属于同一作用域。

在这里插入图片描述

  • 现象
function foo(x = x) {
    console.log(x) // 无实参时报错,TDZ 
}
foo()
let x = 1;
function foo(x = x) {
    console.log(x) // 无实参时报错,2
}
foo(2)
// 不报错!
function bar(x = 2, y = x) {
  return [x, y];
}
bar(); // [2, 2]

注意

var w = 1, z = 2;
function foo(x = w + 1, y = x + 1, z = z + 1) {
    // 报错地方在z
    // Uncaught ReferenceError: Cannot access 'z' before initialization
    console.log(x, y, z)
}
foo()
  • 形参默认值 - 惰性求值,不缓存,每次都重新计算
let a = 99;
function foo(b = a + 1) {
    console.log(b)
}
foo() // 100
a = 100
foo() // 101

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 在项目中的应用
    在这里插入图片描述

3 数组解构

  • 模式匹配(结构化赋值)
  • 解构失败时,结果为undefined
  • 不完全解构:提供的值比需要解构的变量多
  • 变量给默认值+解构
let [a = 6] = [1]
console.log(a) // 1
let [a = 6] = []
console.log(a) // 6
// 解构失败,模式不匹配
let [a = 6] = {} // 报错
// {} is not iterable
console.log(a)
let [a, b = 6] = [1, undefined]
console.log(a, b) // 1 6
let [a, b = 6] = [1, null]
console.log(a, b) // 1 null
let [a = 1, b = a] = []
console.log(a, b) // 1 1
let [a = 1, b = a] = [2]
console.log(a, b) // 2 2

4 对象解构

let firstName = 'Jessica';
let lastName = 'Jung';
let superIdol = {
    [firstName + lastName]: 'owner of e&b'
}
console.log(superIdol)

在这里插入图片描述
在这里插入图片描述

  • 解构语句的语法报错:认为等号左边是语法块
    在这里插入图片描述

  • ()变成表达式
    在这里插入图片描述
    在这里插入图片描述

  • 声明变量时不要乱加括号

[(b)] = [3];
console.log(b); // 3
({a:(b) = {}}) // 本身没有进行匹配,而是默认值
console.log(b); // {}
  • 变量值互换
let a = 1, b = 100;
[a, b] = [b, a]
console.log(a, b) // 100 1

在这里插入图片描述

5. 解构本质

事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。

  • 变量的解构就是变量的赋值
  • 模式匹配可以匹配同源属性
    在这里插入图片描述
var x = 200, y = 300, z = 100;
var obj1 = {
    x: {
        y: 42
    },
    z: {
        y: z
    }
};
({ y: x = { y: y } } = obj1);// x = {y: y} → x = {y: 300}
({ z: y = { y: z } } = obj1);// y = {y: z} → y = {y: 100} 
({ x: z = { y: x } } = obj1);// z = {y: 42}

console.log(x.y, y.y, z.y) // 300 100 42
function test([x, y]) { // 报错
    // Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
    console.log(x, y) 
}
test()
function foo({ x = 10 } = {}, { y } = { y: 10 }) {
    console.log(x, y)
}
foo() // 10 10
foo({}, {}) // 10 undefined
foo({x: 2}, {y: 3}) // 2 3

注意

({ x = 10 } = {});
// ({ x: x = 10 } = {}); 以上是属性和变量相同时的es6写法
({ y } = { y: 10 });
// ({ y: y } = { y: 10 });
console.log(x, y); // 10 10

6 解构的隐式转换

  • 字符串隐式转换类数组
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
  • 数字类型/布尔值隐式转换为包装类
    在这里插入图片描述

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

7. 对函数length属性的影响

  • 当函数形参给默认值时,从当前位置及之后都不计入length(形参个数)的计算
  • 也就是说,指定了默认值后,length属性将失真。
  • 这是因为length属性的含义是,该函数预期传入的参数个数。某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了。同理,后文的 rest 参数也不会计入length属性。
function test(a, b, c = 0) {
}
console.log(test.length) // 2
  • 如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。
function test(c = 0, a, b) {
}
console.log(test.length) // 0
  • 形参实参的映射关系不再成立

8. 函数默认值与作用域

相当复杂的一系列例子

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值