JS解构及数组对象操作

解构

概念

  1. 展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;
  2. 还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。
  3. (译者注: 字面量一般指 [1, 2, 3] 或者 {name: “mdn”} 这种简洁的构造方式)
  4. 来源:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax

解构的时候,变量从左到右一一和元素对齐,可变参数放到变量的最右边

参数解构

function myFn(x,y,z){
    console.log(x,y,z)
}

myFn(...[2,3,4])

列表解构

var parts = ["a","c"];
var test1 = ["head",...parts,"tail"];
console.log(test1)

数组解构

  • 数据解构,等号左边必须使用中括号[]

  • 等号左边变量个数 == 数组元素个数

const arr = [100,200,300];
let [x,y,z] = arr;

console.log(x,y,z)

// 100 200 300
  • 等号左边变量个数 < 数组元素个数
    • 从左至右一一对应,多余的数组元素舍弃
const arr = [100,200,300];
let [x,y] = arr;

console.log(x,y);

// 100 200
  • 等号左边变量个数 > 数组元素个数
    • 多余变量返回undefined
const arr = [100,200,300];
let [x,y,z,a,b] = arr;

console.log(x,y,z,a,b);

// 100 200 300 undefined undefined
  • 等号左边使用丢弃变量
    • JS中,丢弃变量不用写,使用逗号间隔即可
const arr = [100,200,300];
let [,y,,a] = arr;

console.log(y,a);

// 300 undefined
  • 可变变量(剩余变量)
    • 可变变量必须放在最后,参考函数参数
    • 可变变量将收集到的元素封装成数组
const arr = [100,200,300];
let [x,...y] = arr;

console.log(x,y); // 返回100 [200,300]

// 可变变量必须放在最后
// [...y,x] = arr // SyntaxError: Rest element must be last element
  • 支持默认值
    • 变量对应上等号右边的元素,则返回此元素
    • 否则,有默认值返回默认值,没有默认值,返回undefined
const arr = [100,200,300,400,500];
const [x=1,,,,y,z=600] = arr

console.log(x,y,z)
  • 易错点
const arr = [100,200,300,400,500];
// const a,b,c = arr // SyntaxError
// e,f,d = arr; // ReferenceError
var a,b,c = arr; // var定义可以悬空,不带分号有时候会出错
let x,y,z = arr; // let定义可以悬空
[e,f,d] = arr;

console.log(a,b,c); // undefined undefined [ 100, 200, 300, 400, 500 ]
console.log(x,y,z);
console.log(e,f,d); 

// 常量定义不能悬空,必须定义成功指向一个对象
// const a,b,c -- 逗号表达式,返回最后一个变量c,即c = arr,而变量a和b悬空,抛异常

能对应到数据就返回数据;对应不到数据,变量有默认值返回默认值,无默认值则返回undefined


对象解构

  • 对象解构时,需要提供对象的属性名
    • 根据属性名找到对应的值,返回对应的值
    • 没有找到对应的值,属性有缺省值返回缺省值,无缺省值返回undefined
const obj = {
    a:100,
    b:200,
    c:300
};

var {x,y,z} = obj;
console.log(x,y,z); // undefined undefined undefined

var {a,b,c} = obj;
console.log(a,b,c); // 100 200 300

var {a,b,y=400} = obj;
console.log(a,b,y); // 100 200 400
  • 支持别名
    • 应用场景:常量定义中,一个标识符只能出现一次,使用别名
const obj = {
    a:100,
    b:200,
    c:300
};

const {a:x,b,d:z="test"} = obj;
console.log(x,b,z); // 有别名必须使用别名,无别名使用原名

// 100 200 test

复杂解构

  • 嵌套数组
const arr = [1,[2,3],4];

// 等号左边的数据结构不对应等号右边的数据解构
const [x,y,z] = arr;
console.log(x,y,z); // 1 [ 2, 3 ] 4

// 等号左边的数据结构对应等号右边的数据解构,一一对应
const [a,[b,c],d] = arr;
console.log(a,b,c,d); // 1 2 3 4

const [e,f] = arr;
console.log(e,f); // 1 [ 2, 3 ]

const [g,h,i,j=18] = arr;
console.log(g,h,i,j) // 1 [ 2, 3 ] 4 18

const [k,...l] = arr;
console.log(k,l) // 1 [ [ 2, 3 ], 4 ]
  • 对象
var data = {
    a:100,
    b:[
        {
            c:200,
            d:[],
            a:300
        },
        {
            c:1200,
            d:[1],
            a:130
        }
    ],
    c:500
};

console.log(data);

// 注意:等号两边数据结构一致
var {a,b:[{a:m},{a:n}]} = data; // b:[]为对应数据结构,{a:m}为别名
console.log(a,m,n); // 100,300,130

操作

数组的操作

方法描述
push(…items)尾部增加多个元素,返回元素增加后的数组长度
pop移出最后一个元素,并返回这个元素
map引入处理函数来处理数组中的每一个元素,返回新的数组
filter引入处理函数来处理数组中的每一个元素,处理函数返回true的元素保留,否则元素被过滤,保留的元素封装成新的数组返回
foreach迭代所有元素,无返回值
  • push、pop
const arr = [1,2,3,4,5];

console.log(arr,arr.push(6,10)); // [ 1, 2, 3, 4, 5, 6,10 ] 7
// 从左至右依次执行,全部执行完毕才打印,索引arr为[ 1, 2, 3, 4, 5, 6,7 ]
// 注意,不是执行一个就打印一个

console.log(arr,arr.pop()) // [ 1, 2, 3, 4, 5, 6 ] 10
  • map(callbackfn: (value: T, index: number, array: T[])=> U, thisArg: any)
    • callbackfn,程序员自己写,callbackfn (第一参数value返回值,第二参数index返回索引,第三参数array返回数组本身) {return推荐数组}
    • 处理后的元素个数不会发生变化,参考Python的map
const arr = [1,2,3,4,5];

m = arr.map((x) => x+1); 
m1 = arr.map((x) => [x+1,x+2]); 
m2 = arr.map((x,y,z) => {console.log(x,y,z)});

console.log(m) // [ 2, 3, 4, 5, 6 ]
console.log(m1) // [ [ 2, 3 ], [ 3, 4 ], [ 4, 5 ], [ 5, 6 ], [ 6, 7 ] ]
console.log(m2) // [ undefined, undefined, undefined, undefined, undefined ]
  • filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any)
    • callbackfn,程序员自己写,callbackfn (第一参数value返回值,第二参数index返回索引,第三参数array返回数组本身) {return推荐数组}
    • 处理后的元素个数不变或者减少,参考Python的filter
const arr = [1,2,3,4,5];

f = arr.filter((x) => {return (x & 1) == 0;}) 
f1 = arr.filter((x) => {(x & 1) == 0;}) // 每次迭代,返回undefined,等价false,所有没有结果
console.log(f) // [2,4]
console.log(f1) // []
  • forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any)
    • callbackfn,程序员自己写,callbackfn (第一参数value返回值,第二参数index返回索引,第三参数array返回数组本身) {无返回值}
const arr = [1,2,3,4,5];

// 
f = arr.forEach((x) => {console.log(x);y = x+1;return y})
console.log(f)

/* 返回结果,等效for...of循环遍历打印
1
2
3
4
5
undefined 回调函数中,return语句不起作用,无返回值 */

// 应用
let target = new Array()

arr.forEach((x) => {target.push(x**2)})
console.log(target)

数组练习 – 需要考虑性能

  • 有一个数组const arr = [1,2,3,4,5];,算出所有元素平均值,且输出平方值是偶数且大于10的平方值

  • 方法一

    • 先计算,后判断偶数、是否大于10,效率较低
const arr = [1,2,3,4,5];

var target = arr.map(x => x*x).filter(
        (x) => {if (x > 10 && (x & 1) == 0){return x}}
        )

console.log(target)
  • 方法二
    • 先判断偶数、是否大于10,后计算
const arr = [1,2,3,4,5];

var s = Math.sqrt(10); // 大于10的开方值,才能通过
var target = [];

arr.forEach((x) => {
    if (x > s && (x & 1) == 0){
        target.push(x * x)
    }
})

console.log(target)

对象的操作

Object的静态方法描述
Object.keys(obj)ES5开始支持;返回所有key
Object.values(obj)返回所有的value,实验阶段,支持较差
Object.entries(obj)返回所有的key_value,实验阶段,支持较差
Object.assign(target,…sources)使用多个source对象,来填充target对象,返回target对象
const obj = {
    a:100,
    b:200,
    c:300
};

console.log(Object.keys(obj)); // [ 'a', 'b', 'c' ]
console.log(Object.values(obj)); // [ 100, 200, 300 ]
console.log(Object.entries(obj)); // [ [ 'a', 100 ], [ 'b', 200 ], [ 'c', 300 ] ]

var ass_obj = Object.assign(
    {},
    obj,
    {a:1000,b:2000},//覆盖target中的a、b属性对应的值
    {c:'abc'}, /* 覆盖 */
    {c:3000,d:"python"} /* 有则覆盖,无则追加 */
);

console.log(ass_obj);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值