ES语法扩展

news2024/10/6 8:31:52

剩余参数 

剩余参数本质

// 剩余参数的本质
    const add=(x,y,...args)=>{
        console.log(x,y,args);
    }
    add();
    add(1);
    add(1,2);
    add(1,2,3,4,5);

剩余参数的注意事项

  • 箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号
  • 使用剩余参数替代arguments获取实际参数
  • 剩余参数的位置只能是最后一个参数,之后不能再有其他参数,否则会报错
// const add=function (){
    //     console.log(arguments);
    // }
    
    // 箭头函数不能用arguments对象
    // const add=()=>{
    //     console.log(arguments);
    // }
    const add=(...args)=>{
        console.log(args);
    }
    add(1,2);

特别注意:arguments对象在箭头函数不能使用

剩余参数的应用

剩余参数可以是数组也可以是对象

// 与解构赋值一起使用
    // 剩余参数不一定非要作为函数参数使用
    // 必须是最后一个
    const [num,...args]=[1,2,3,4];
    console.log(num,args);

    const func=([n,...args])=>{
        console.log(n,args);
    };
    func([1,2,3]);

    // ...z代表剩余元素比较合适
    const {x,y,...z}={a:1,x:2,y:3,b:4};
    console.log(x,y,z); //z是一个对象

    const func1=({x,y,...z})=>{
        console.log(x,y,z); //z是一个对象
    };
    func1({a:1,x:2,y:3,b:4});

数组的展开运算符

Math.min()括号里面必须是参数列表,不能是数组,把它转为展开运算符即可使用

console.log(Math.min(...[1,2,3]));    //1
    console.log(Math.min(3,1,2));    //1

区分剩余参数和展开运算符

// 本质区别
    // 展开运算符
    // [3,1,2]->3,1,2
    // 剩余参数
    // 3,1,2->[3,1,2]
    const add=(...args)=>{
        console.log(args);  //剩余参数
        console.log(...args);   //展开运算符
    }
    add(1,2,3);
    // 二维数组转为一维数组
    console.log([...[1,2,3],4]);

数组展开运算符的应用

// 1.复制数组
    const a=[1,2];
    const b=[...a];
    a[0]=3;
    console.log(a);
    console.log(b);
    // 2.合并数组
    const c=[1,2];
    const d=[3];
    const e=[4,5];
    console.log([...d,...c,...e]);
    // 3.字符串转为数组
    // 字符串可以按照数组的形式展开
    console.log(...'alex');
    console.log('a','l','e','x');
    console.log([...'alex']);
    console.log('alex'.split(''));
    // 4.常见的类数组转化为数组
    // arguments和NodeList
    function func(){
        console.log(arguments);
        console.log([...arguments]);
    }
    func(1,2);
    // NodeList
    console.log(document.querySelectorAll('p'));
    console.log([...document.querySelectorAll('p')].push);

对象的展开运算符 

对象的展开:把属性罗列出来,用逗号分隔,放到一个{}中,构成新对象

// 1.展开对象
    // 对象不能直接展开,必须在花括号里展开
    const apple = {
        color: '红色',
        shape: '球形',
        taste: '甜'
    };
    // 新对象
    console.log({...apple});
    console.log({...apple} === apple);  //false
    // 2.合并对象
    const pen={
        color: '黑色',
        shape: '圆柱形',
        use:'写字'
    };
    // 新对象拥有全部属性,相同属性,后者覆盖前者
    console.log({...pen,...apple});

对象展开运算符的注意事项

// 1.空对象的展开
    // 如果展开一个空对象,则没有任何效果
    console.log({...{}});
    console.log({...{},a:2});

    // 2.非对象的展开
    // 如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来
    console.log({...1});
    console.log(new Object(1)); // 对象Number{1},里面没有任何属性
    console.log(new Object(undefined)); // {}.里面没有任何属性
    console.log(new Object(null)); // {},里面没有任何属性
    console.log(new Object(true)); // 对象Boolean{true},里面没有任何属性

    // 如果展开运算符后面是字符串/数组,它会自动转成一个类似数组的对象
    // 返回的不是空对象
    console.log({...'alex'});
    console.log([...'alex']);
    console.log({...[1,2,3]});

    // 3.对象中对象属性的展开
    // 特点:不会展开对象中的对象属性
    const apple={
        feature:{
            taste:'甜'
        }
    };
    const pen={
        feature: {
            color:'黑色',
            shape:'圆柱形'
        },
        use:'写字'
    };
    console.log({...apple});
    console.log({...apple,...pen});

对象展开运算符的应用

// 用户参数和默认参数
    const logUser=userParam=>{
        const defaultParam={
            username:'Alex',
            age:0,
            sex:'male'
        }
        // const param={...defaultParam,...useParam};
        // console.log(param.username,param.age,param.sex);
        const {username,age,sex}={...defaultParam,...userParam};
        console.log(username,age,sex);
    }
    logUser();
    logUser({username:'张三'});

调用logUser()方法,用户参数userParam为undefined,这时...userParam为{},所以{username,age,sex}跟默认参数一样 

Set和Map数据结构

Set数据结构

Set是一系列无序、没有重复值的数据集合 

方法有:add、has、delete、clear、forEach 属性有:size

const s=new Set();
    s.add(1);
    s.add(2);
    s.add(3);
    // Set中不能有重复的成员
    s.add(1);
    console.log(s);
    // Set没有下标去标示每一个值,所以Set是无序的,
    // 也不能像数组那样通过下标去访问Set的成员

    // 遍历(按照成员添加进集合的顺序遍历)
    s.forEach(function (value,key,set){
        // Set中value和key相等 为了统一
        console.log(value,key,set===s);
        //console.log(this);  // 非严格模式下undefined转为window
    })

Set构造函数的参数 

<p>1</p>
<p>2</p>
<p>3</p>
<script>
    // 1.数组
    const s = new Set([1, 2, 1]);
    console.log(s);
    // 2.字符串、arguments、nodeList、Set实例等
    console.log(new Set('hi'));

    function func() {
        console.log(new Set(arguments));
    }

    func(1, 2, 1);
    console.log(new Set(document.querySelectorAll('p')));
    console.log(new Set(s) === s);
</script>

Set的注意事项

  • 判断重复set方式
  • 什么时候使用set
// 1.判断重复的方式
    const s=new Set([1,2,1,NaN,NaN]);
    console.log(1===1);//true
    console.log(NaN===NaN);//false
    // Set对重复值的判断基本遵循严格相等(===)
    // 但是对于NaN的判断与===不同,Set中NaN等于NaN
    console.log(s);

    const s1=new Set();
    s1.add({}).add({});
    console.log({}==={});   //引用类型看内存地址是否相同
    console.log(s1);

    // 2.什么时候使用Set
    // (1)数组或字符串去重时
    // (2)不需要通过下标访问,只需要遍历时
    // (3)为了使用Set提供的方法和属性

Set的应用

// 1.数组去重
    const s=new Set([1,2,1]);
    console.log(s);
    console.log(...s);
    console.log([...s]);
    console.log([...new Set([1,2,1])]);

    // 2.字符串去重
    const s1=new Set('abcddcba');
    console.log(s1);
    console.log(...s1);
    console.log([...s1].join(''));

    // 3.存放dom元素
    console.log(document.querySelectorAll('p'));
    const s2=new Set(document.querySelectorAll('p'));
    console.log(s2);
    s2.forEach(function (element){
        console.log(element);
        element.style.color='red';
        element.style.backgroundColor='yellow';
    })

 

Map数据结构 

Map和对象都是键值对的集合

对象一般用字符串当作键,因为是合法的标识符,通常引号可省略

const obj = {
        'name': 'alex',
        true: true,
        [{}]: 'object'
    };
    console.log(obj);
    console.log({}.toString());
    // 基本数据类型:数字、字符串。布尔值、undefined、null
    // 引用数据类型:对象([]、{}、函数、Set、Map等)
    // 以上都可以作为Map的键
    const m = new Map();
    m.set('name', 'alex');
    m.set(true, 'true');
    m.set({}, 'object');
    m.set(new Set([1, 2]), 'set');
    m.set(undefined, 'undefined');
    console.log(m);

// 1.set方法
    // 使用set添加的新成员,键名如果已经存在,后添加的键值对覆盖前面的
    const m=new Map();
    m.set('age',18).set(true,'true').set('age',20);
    console.log(m);
    // 2.get方法
    // get获取不存在的成员,返回undefined,不会报错
    console.log(m.get('age'));
    console.log(m.get(true));
    // 3.has方法
    console.log(m.has('age'));
    // 4.delete方法
    // 删除不存在的成员,什么都不会发生,也不会报错
    m.delete('age');
    m.delete('name');
    console.log(m);
    // 5.clear方法
    m.clear();
    console.log(m);
    // 6.forEach方法
    m.set('age',18).set(true,'true').set('age',20);
    m.forEach(function (value,key,map){
        console.log(value,key,map===m);
        console.log(this);
    })
    // size属性
    console.log(m.size);

Map构造函数的参数

// 1.二维数组
    console.log(new Map([
        ['name','alex'],
        ['age',18]
    ]));
    // 2.Set、Map等
    // Set也必须体现出键和值
    const s=new Set([
        ['name','alex'],
        ['age',20]
    ]);
    console.log(new Map(s));
    console.log(s);
    // Map
    const m1=new Map([
        ['name','alex'],
        ['age',22]
    ]);
    console.log(m1);
    const m2=new Map(m1);
    console.log(m2);
    console.log(m2===m1);

Map的注意事项

  • 判断键名是否相同的方式
  • 什么时候使用Map
// 1.判断键名是否相同的方式
    // 基本遵循严格相等(===)
    // 例外就是NaN,Map中NaN等于NaN
    const m=new Map();
    m.set(NaN,1).set(NaN,2);
    console.log(m);
    
    // 2.什么时候使用Map
    // (1)只需要key->value的结构
    // (2)需要字符串以外的值做键名

Map的应用

// 解构赋值
    const [p1, p2, p3] = document.querySelectorAll('p');
    //console.log(p1,p2,p3);
    const m = new Map([
        [p1, {
            color: 'red',
            backgroundColor: 'yellow',
            fontSize: '40px'
        }],
        [p2, {
            color: 'green',
            backgroundColor: 'pink',
            fontSize: '40px'
        }],
        [p3, {
            color: 'blue',
            backgroundColor: 'orange',
            fontSize: '40px'
        }]
    ]);
    m.forEach((propObj, element) => {
        for (const p in propObj){
            element.style[p]=propObj[p];
        }
    });

遍历

// 使用iterator 可遍历对象
    const it=[1,2][Symbol.iterator]();
    console.log(it.next());
    console.log(it.next());
    console.log(it.next());
    // Symbol.iterator: 可遍历对象的生成方法

 

我们一般不会直接使用iterator去遍历(Symbol.iterator->it->next())

遍历数组:for循环和forEach方法

遍历对象:for in循环 

console.log([][Symbol.iterator]());
    console.log({}[Symbol.iterator]);

for…of用法 

  • 与break、continue一起使用
  • 在for…of中取得数组的索引
  • for...of循环只会遍历出那些done为false时对应的value值
// 1.for...of循环本质
    const arr=[1,2,3];
    // const it=arr[Symbol.iterator]();
    // let next=it.next();
    // //console.log(next);
    // while (!next.done){
    //     console.log(next.value);
    //     next=it.next();
    // }

    for (const item of arr) {
        console.log(item);
    }
    // 2.用法
    // 在for...of获得索引
    // keys()得到的是索引的可遍历对象,可以遍历出索引值
    console.log(arr.keys());
    for (const key of arr.keys()) {
        console.log(key);
    }
    // values()得到的是值的可遍历对象,可以遍历出值
    console.log(arr.values());
    for (const value of arr.values()) {
        console.log(value);
    }
    // entries()得到的是索引+值组成的数组的可遍历对象
    for (const entries of arr.entries()) {
        console.log(entries);
    }
    // 解构赋值
    for (const [index, value] of arr.entries()) {
        console.log(index,value);
    }

 

原生可遍历与非原生可遍历 

只要有Symbol.iterator方法,并且这个方法可以生成可遍历对象,就是可遍历的 

原生可遍历的有:数组、字符串、Set、Map、函数的arguments对象、NodeList 

非原生可遍历的有:一般的对象、有length和索引属性的对象

const person={
        sex:'male',
        age:18
    };
    person[Symbol.iterator]=()=>{
        let index=0;
        return{
            next(){
                index++;
                if (index===1){
                    return{
                        value:person.age,
                        done:false
                    }
                }else if (index===2){
                    return {
                        value: person.sex,
                        done: false
                    }
                }else {
                    return {
                        done: true
                    }
                }
            }
        }
    };
    for (const item of person) {
        console.log(item);
    }

const obj={
        0:'alex',
        1:'male',
        length:2
    };
    // obj[Symbol.iterator]=Array.prototype[Symbol.iterator];
    obj[Symbol.iterator]=()=>{
        let index=0;
        return{
            next(){
                let value,done;
                if (index<obj.length){
                    value=obj[index];
                    done=false;
                }else {
                    value=undefined;
                    done=true;
                }
                index++;
                return{
                    value,done
                }
            }
        }
    };
    for (const item of obj) {
        console.log(item);
    }

使用了Iterator的场合

对原生可遍历的:数组、字符串、Set、Map、函数的arguments对象、NodeList 

  • 数组的展开运算符
  • 数组的解构赋值
  • Set和Map的构造函数
// 1.数组的展开运算符
    console.log(...[1,2,3]);
    console.log(...'str');
    console.log(...new Set([1,2,3]));
    // 2.数组解构赋值(不需要结构匹配)
    // 形式:[...]
    console.log([...'hi']);
    const [a,b]='hi';
    // 相当于const [a,b]=[...'hi'];
    console.log(a,b);

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.Isaac Jetson Nano 入门

Isaac Jetson Nano 入门 本节介绍如何在 Jetson Nano 设备上运行 Isaac SDK 示例应用程序。 有关如何开始使用 Nano 的一般说明&#xff0c;请参阅 Jetson Nano 开发工具包入门。 文章目录Isaac Jetson Nano 入门获取 IP 地址在 Jetson Nano 上运行示例应用程序PingOpenCV 边缘…

Pytorch CIFAR10图像分类 EfficientNet v1篇

Pytorch CIFAR10图像分类 EfficientNet v1篇 文章目录Pytorch CIFAR10图像分类 EfficientNet v1篇4. 定义网络&#xff08;EfficientNet&#xff09;EfficientNet介绍EfficientNet性能比较EfficientNet的baselineEfficientNet模型混合缩放方法其他版本的EfficientNet(B1-B7)判断…

错题 3jxn (8253复杂)

A 指示型指令 C 比如 ,跟C语言的return 一样&#xff0c;可以由多条&#xff0c;但是返回的位置都是一个地方 JN NEXT RET NEXT: RET A 可以重复 EQU不可以重复 C 中断向量&#xff1a;中断服务程序的入口地址 向量中断&#xff1a;识别中断你的方法 接口 编程题&#xff…

Redis关键知识点总结

Reference: http://redis.cn用处缓存数据库分布式锁&#xff08;Redission的redlock&#xff0c;自定义的lock等&#xff09;过滤器&#xff08;布隆过滤器/增强的带计数的布隆过滤器/布谷鸟过滤器等&#xff09;大规模的计算辅助&#xff08;bitmap&#xff09;消息订阅/监听 …

PyQt5入门学习(一)【小白入门系列】

PyQt5入门学习 介绍&#xff1a;PyQt5是Python较好的图形库&#xff0c;与C的Qt不同的是PyQt5封装得较为简单&#xff0c;上手也更加的方便。下面话不多说&#xff0c;开始学习PyQt5吧&#xff01; 安装过程 安装方法有两种&#xff0c;一种是下载PyQt5最新源码进行编译安装…

初识Kafka

1.1 定义 Kafka传统定义: Kafka是一个分布式的基于发布/订阅模式的消息队列(MessageQueue&#xff09;&#xff0c;主要应用于大数据实时处理领域。 发布/订阅: 消息的发布者不会将消息直接发送给特定的订阅者&#xff0c;而是将发布的消息分为不同的类别&#xff0c;订阅者只…

[数据结构基础]二叉树——堆的概念、结构、接口函数及经典的Topk问题和堆排序问题

目录 一. 堆的概念及结构 1.1 堆的概念 1.2 堆的结构及在内存中的存储 二. 堆的主要接口函数 2.1 堆初始化函数HeapInit 2.2 堆销毁函数HeapDestroy 2.3 向堆中插入数据函数HeapPush&#xff08;以小堆为例&#xff09; 2.4 删除堆根节点数据函数HeapPop&#xff08;小…

C++ 夺冠!成为 TIOBE 2022 年度编程语言

目录&#xff1a;C夺冠—成为TIOBE2022年度编程语言一、前言二、C 摘得桂冠三、Top 10 编程语言 TIOBE 指数走势&#xff08;2002-2023&#xff09;四、历史排名&#xff08;1987-2023&#xff09;五、编程语言“名人榜”&#xff08;2003-2022&#xff09;六、说明一、前言 2…

vitepress(三):自动生成目录

上一节我们将自己的网站发布到了git pages上&#xff0c;但是现在我们需要每次更新一篇文章就重写一次目录&#xff0c;操作上十分的繁琐和不方便&#xff0c;所以我们需要一个方法去自动生成我们的侧边栏结构&#xff0c;方便我们每次只需要更新我们的项目即可。这里我们要知道…

【每日一题】【LeetCode】【第六天】【Python实现】加一

加一的解决之路 题目描述 测试案例&#xff08;部分&#xff09; 第一次 1这个很好理解&#xff0c;唯一的难点就是个位1导致的进位的问题&#xff0c;可能会只会导致十位1&#xff0c;也有像8999这样产生多次进位的情况。 为了解决进位问题&#xff0c;自己想到了第三天学…

mysql三表查询15个例子带你搞懂它

mysql三表查询30个经典案例创建三个表a、b、c表a中的数据表b中的数据表c中的数据1.查询出学习成绩70分以上的学生姓名与成绩与学科&#xff1b;2.查询姓名以mi结尾的学生姓名及其任课老师姓名&#xff1b;3.选修课名为math的学生学号与姓名;4.选修课号为C4的学生学号&#xff1…

QEMU调试Linux内核环境搭建

一个最小可运行Linux操作系统需要内核镜像bzImage和rootfs&#xff0c;本文整理了其制作、安装过程&#xff0c;调试命令&#xff0c;以及如何添加共享磁盘。编译内核源码从 The Linux Kernel Archives 网站下载内核源码&#xff0c;本文下载的版本为4.14.191&#xff0c;4.14.…

危险程度(并查集)

有 nn 种化学物质&#xff0c;编号 1∼n1∼n。 其中&#xff0c;有 mm 对物质之间会发生反应。 现在&#xff0c;要将这些化学物质逐个倒入同一个试管之中&#xff0c;具体倒入顺序不限。 我们需要计算一下试管的危险值。 已知&#xff0c;空试管的危险值为 11&#xff0c;…

【UE4 第一人称射击游戏】21-添加动态扩散准心

素材资料地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1epyD62jpOZg-o4NjWEjiyg密码&#xff1a;jlhr上一篇&#xff1a;【UE4 第一人称射击游戏】20-添加瞄准十字线本篇效果&#xff1a;步骤&#xff1a;将资源移至FPS项目文件夹内移入后发现多了一个名为“WBCro…

【web安全】——报错注入

作者名&#xff1a;Demo不是emo主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座右…

如何查看sqlite数据库的 .db文件中的表的内容数据

在使用 qt 的sqlite 数据的时候,对于创建的数据库的 .db 文件的内容的查看我们可以按照下面的步骤安装工具进行查看 下载所需的sqlite 查看工具 下载:链接&#xff1a;https://pan.baidu.com/s/1KSl9w61zaEyemhR1Ir04_A 提取码&#xff1a;6666 只需要解压即可,其中安装包内…

MINISForum HX90 主机风扇调教

今年秋天买了个1个HX90 5900H的mini主机。准系统版本&#xff0c;2899元。 但是买回来之后&#xff0c;发现它的风扇声音实在是大&#xff0c;稍微一加载点东西&#xff0c;就 开始呜呜的响&#xff0c;简直让人心烦 意乱。 去了官网查看。好多人的解决办法看了没看明白&…

【机器学习】PR曲线F1评分ROC曲线AUC

参考&#xff1a;《百面机器学习》 PR曲线 TP&#xff08; True Positive&#xff09;&#xff1a;真正例 FP&#xff08; False Positive&#xff09;&#xff1a;假正例 FN&#xff08;False Negative&#xff09;&#xff1a;假反例 TN&#xff08;True Negative&#xff0…

基于imx6ull配置开发环境

1. 交叉编译链背景&#xff1a;因为在原子的教程中有强调最新的Linaro gcc编译完uboot后无法运行的问题&#xff0c;所以原子采用4.9&#xff0c;那我们就沿用下。Linaro gcc有两个版本: gcc-linaro-4.9.4-2017.01-i686_arm-linux-gnueabihf.tar.tar.xz 和 gcc-linaro-4.9.4-20…

linux反弹备忘录

如果你有幸在渗透测试中发现了命令执行漏洞&#xff0c;那么不久之后你可能需要一个交互式shell。如果无法添加新帐户/ SSH密钥/ .rhosts文件并登录&#xff0c;则下一步可能是拖回反向shell或将shell绑定到TCP端口。 本页讨论前者。创建反向 shell 的选项受到目标系统上安装的…