ES6,DAY2

本文详细讲解了ES6中rest参数的使用,如何用它替代ES5的arguments,并展示了扩展运算符在参数传递中的应用。此外,还介绍了Symbol的基本用法,包括创建独特属性、内置值如hasInstance和isConcatSpreadable,以及迭代器和生成器的实战示例。
摘要由CSDN通过智能技术生成

rest参数

先看ES5中的Arguments,获取实参的方式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>rest参数</title>
</head>
<body>
    <script>
        // ES6引入rest参数,用于获取函数的实参,用来代替arguments
        // ES5中获取实参的方式
        function date(){
            console.log(arguments);
        }
        date('白芷','阿娇');
    </script>
</body>
</html>

在这里插入图片描述
使用ES6的rest参数,输出是数组的形式。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>rest参数</title>
</head>

<body>
    <script>
        // ES6引入rest参数,用于获取函数的实参,用来代替arguments
        // ES5中获取实参的方式
        // function date(){
        //     console.log(arguments);
        // }
        // date('白芷','阿娇');

        // rest参数
        function date(...args) {
            // 输出的结果在浏览器中是数组的形式
            console.log(args);
        }
        date('白芷', '阿娇')
        // rest参数必须要放到最后,在网页输出中可以看到,a和b输出的是数,args是数组的形式
        function cv(a, b, ...args) {
            console.log(a);
            console.log(b);
            console.log(args);
        }
        cv('1', '2', '3')
    </script>
</body>

</html>

在这里插入图片描述

扩展运算符

在不使用扩展运算符的时候,我们发现,打印输出的内容是数组的形式

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扩展运算符</title>
</head>

<body>
    <!-- 扩展运算符是个符号,符号的形式是 ... 能把数组转换为逗号分隔的参数序列 -->
    <script>
        const tf = ['哈哈', '呵呵', '嘎嘎'];
        // 声明一个函数
        function zhuanhuan() {
            console.log(arguments);
        }
        zhuanhuan(tf)
    </script>
</body>

</html>

在这里插入图片描述
当使用扩展运算符后。变成了三个实参。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扩展运算符</title>
</head>

<body>
    <!-- 扩展运算符是个符号,符号的形式是 ... 能把数组转换为逗号分隔的参数序列 -->
    <script>
        const tf = ['哈哈', '呵呵', '嘎嘎'];
        // 声明一个函数
        function zhuanhuan() {
            console.log(arguments);
        }
        zhuanhuan(...tf);
    </script>
</body>

</html>

在这里插入图片描述

扩展运算符的应用

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扩展运算符的应用</title>
</head>

<body>
    <div></div>
    <div></div>
    <div></div>
    <script>
        // 1.数组的合并
        const kuaizi = ['旺旺', '漏喽'];
        const fenghuang = ['卡卡', '哦哦'];
        // 普通数组合并
        // const wudi = kuaizi.concat(fenghuang);
        // 打印wudi,在网页输出中可以看到,输出了四个参数
        // console.log(wudi);
        // 使用扩展运算符数组合并
        // 打印wudi,网页输出中可以看到一样的效果
        const wudi = [...kuaizi, ...fenghuang]
        console.log(wudi);
        // 2.数组的克隆
        const qq = ['a', 'b', 'c'];
        const ww = [...qq];
        // 输出的ww和qq的内容一样
        console.log(ww);
        // 3.将伪数组转换为真正的数组
        const divs = document.querySelectorAll('div');
        const divarr = [...divs]
        console.log(divarr);
    </script>
</body>

</html>

在这里插入图片描述

Symbol基本使用

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Symbol基本使用</title>
</head>

<body>
    <!-- ES6引入了一种新的数据类型 -->
    <script>
        // 创建symbol,通过一个函数
        let s = Symbol();
        // 打印一下s以及s的类型,网页后台打印输出的类型是“symbol”
        console.log(s, typeof s);
        // 第二种创建的方式,还能传入一个字符串
        let s2 = Symbol('哈哈');
        let s3 = Symbol('哈哈');
        // 我们打印输出一下,s2和s3是否一样,实际输出为false
        // 可以理解为有两个张三,但是张三的编号是不一样的
        console.log(s2 === s3);
        // 第三种方式,symbol.for()创建
        // symbol.for访问的是全局的symbol表,如果有了就访问对应对象,没有就创建
        let s4 = Symbol.for('哈哈');
        let s5 = Symbol.for('哈哈')
        console.log(s4, typeof s4);
        // 这里网页打印输出的是true
        console.log(s4 === s5);
        // 注意,symbol不能与其他数据运算
        // let result = s + 100;
    </script>
</body>

</html>

在这里插入图片描述
小结下,已有的数据类型:
在这里插入图片描述

Symbol使用

symbol创建对象属性

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>symbol创建对象属性</title>
</head>

<body>
    <script>
        // 向对象中添加方法 ,表示其独一无二的特点
        let game = {
        };
        //声明一个方法,都带有symbol属性
        let methods = {
            up: Symbol(),
            down: Symbol()
        };
        game[methods.up] = function () {
            console.log('我可以改变形状');
        }
        game[methods.down] = function () {
            console.log('我可以快速下降');
        }
        // 这样就给对象game中快速添加了方法,每个方法都不同
        // 打印结果输出新加了两个symbol属性
        console.log(game);
        // 举例,给youxi,这个对象添加独一无二的方法
        let youxi = {
            name: "狼人杀",
            say: Symbol(),
            zibao: Symbol()
        }
        youxi[methods.up] = function () {
            console.log('发言');
        }
        youxi[methods.down] = function () {
            console.log('自爆');
        }
        // 打印结果输出有四个symbol
        console.log(youxi);
    </script>
</body>

</html>

在这里插入图片描述

Symbol内置值

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Symbol内置属性</title>
</head>

<body>
    <script>
        // 演示Symbol.hasinstance。
        // 定义一个类,里边加入了静态方法
        class Person {
            static [Symbol.hasInstance]() {
                console.log('我被用来检测类型了');
            }
        }
        // 定义一个空对象o
        let o = {};
        // 检验,判断Person是否为空对象o的实例,输出为false
        // 因为我们并没有把Person写在o里边,o是空的
        console.log(o instanceof Person);
        // 演示Symbol.isConcatSpreadabe
        // 
    </script>
</body>

</html>

在这里插入图片描述
演示isConcatSpreadabe属性

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Symbol内置属性</title>
</head>

<body>
    <script>
        // 1.演示Symbol.hasinstance。
        // 定义一个类,里边加入了静态方法
        class Person {
            static [Symbol.hasInstance]() {
                console.log('我被用来检测类型了');
            }
        }
        // 定义一个空对象o
        let o = {};
        // 检验,判断Person是否为空对象o的实例,输出为false
        // 因为我们并没有把Person写在o里边,o是空的
        console.log(o instanceof Person);
        //2. 演示Symbol.isConcatSpreadabe
        const arr = [1, 2, 3];
        const arr2 = [4, 5, 6];
        // 加上这个属性为false后,网页打印出来的是1,2,3,array(3),即没有把数组连接后的arr2展开显示
        arr2[Symbol.isConcatSpreadable] = false;
        // 做数组合并
        console.log(arr.concat(arr2));
    </script>
</body>

</html>

在这里插入图片描述

迭代器

在这里插入图片描述
在js中Iterator接口就是对象里边的一个属性。
下边演示使用for of的循环,

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>迭代器</title>
</head>

<body>
    <script>
        // 声明一个数组
        const xiyou = ['唐僧', '八戒']
        // 使用for of遍历数组
        for (let v of xiyou) {
            console.log(v);
        }
    </script>
</body>

</html>

在这里插入图片描述
注意与for in的区别

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>迭代器</title>
</head>

<body>
    <script>
        // 声明一个数组
        const xiyou = ['唐僧', '八戒']
        // 使用for of遍历数组
        for (let v in xiyou) {
            console.log(v);
        }
    </script>
</body>

</html>

在这里插入图片描述
打印自定义数组的属性,查看有无iterator属性。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>迭代器</title>
</head>

<body>
    <script>
        // 声明一个数组
        const xiyou = ['唐僧', '八戒']
        // 使用for of遍历数组
        for (let v of xiyou) {
            console.log(v);
        }
        // 打印下xiyou的属性,看看有没有iterator这个属性
        console.log(xiyou);
    </script>
</body>

</html>

在这里插入图片描述

迭代器应用

先演示错误的应用,浏览器提示说没有这个iterator接口,因为原生就带有iterator接口的数据中,不包含对象,包含Arr数组、String字符串等等。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定义遍历数据</title>
</head>

<body>
    <script>
        // 自定义遍历数据的时候,要想到迭代器
        const banji = {
            name: "终极一班",
            stus: ['xiaoming', 'xiaoning', 'xiaohong', 'xiaotian']
        }
        // 遍历这个对象
        for(let v of banji){
            console.log(v);
        }
    </script>
</body>

</html>

在这里插入图片描述
演示正确的应用,先看工作原理
在这里插入图片描述
从原理实现了一个迭代器,相当于按照原理封装了一个迭代器。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定义遍历数据</title>
</head>

<body>
    <script>
        // 自定义遍历数据的时候,要想到迭代器
        const banji = {
            name: "终极一班",
            stus: ['xiaoming', 'xiaoning', 'xiaohong', 'xiaotian'],
            // 因为自定义的对象原生属性中没有iterator这个接口,所以自己加上
            // 创建一个指针对象
            [Symbol.iterator]() {
                // 声明一个索引变量
                let index = 0;
                // 声明一个变量保存当前中括号内的this
                _this = this;
                return {
                    // 加上next方法
                    next: function () {
                        // 根据索引值返回遍历的值
                        if (index < _this.stus.length) {
                            // 返回一个包含value和done属性的对象
                            const result = { value: _this.stus[index], done: false };
                            // 下标索引值自增
                            index++;
                            return result;
                        } else {
                            return { value: undefined, done: true }
                        }

                    }
                }
            }
        }
        // 遍历这个对象
        for (let v of banji) {
            console.log(v);
        }
    </script>
</body>

</html>

在这里插入图片描述

生成器

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生成器</title>
</head>

<body>
    <script>
        // 生成器其实就是一个特殊的函数
        // 解决异步编程,传统方式是使用纯回调函数
        function* gen() {
            console.log("哈哈");
            // yield是相当于函数代码的分隔符,把函数代码切成了几块,三个yield切四块
            // 加入后,不像以前一样,该中括号内代码一下就全部执行完毕,现在是分段执行
            yield '一直';
            console.log(222);
            yield '没有';
            console.log(333);
            yield '耳朵';
            console.log(444);
        }
        let iterator = gen();
        console.log(iterator);
        // 借助迭代器方法运行gen里边的代码,因为打印gen之后发现,里边有next指针属性
        iterator.next();
        // 分断执行yield代码,每使用一次iterator.next();,执行一段yield代码
        iterator.next();
        // 输出333
        iterator.next();
        // 输出444
        iterator.next();
    </script>
</body>

</html>

在这里插入图片描述

生成器函数参数

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生成器函数参数</title>
</head>

<body>
    <script>
        function* gen(arg) {
            //打印传进来的形参
            console.log(arg);
            let one=yield 111;
            console.log(one);
            yield 222;
            yield 333;
        }
        // 获取迭代器对象
        // 传入一个形参aaa
        let iterator = gen('aaa');
        // 打印输出执行第一个yield语句隔离的第一段代码的结果
        console.log(iterator.next());
        // 打印输出执行第二个yield语句的结果,同时next方法可以传入实参,作为上一个yield的返回结果
        console.log(iterator.next('bbb'));
        // 打印输出执行第三个yield语句的结果
        console.log(iterator.next());
    </script>
</body>

</html>

在这里插入图片描述

生成器函数实例

解决了回调地狱的问题。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生成器函数实例</title>
</head>

<body>
    <script>
        // 异步编程 文件操作 网络操作(ajax request) 数据库操作
        // 1秒后控制台输出111,2秒后控制台输出222,3秒后控制台输出333
        // 使用传统的嵌套来实现,最后出现了回调地狱,指一层一层嵌套,调用
        // setTimeout(() => {
        //     console.log(111);
        //     setTimeout(() => {
        //         console.log(222);
        //         setTimeout(() => {
        //             console.log(333);
        //         }, 3000)
        //     }, 2000)
        // }, 1000)
        // 使用生成器函数实现,先声明三个函数,实现三个不同任务
        function one() {
            setTimeout(() => { console.log(111); }, 1000)
        }
        function two() {
            setTimeout(() => { console.log(222); }, 2000)
        }
        function three() {
            setTimeout(() => { console.log(333); }, 3000)
        }
        function* gen() {
            // 总共被分割为4段代码
            yield one();
            yield two();
            yield three();
        }
        // 然后调用生成器函数
        let iterator = gen();
        // 调用yield分割后的第一段代码
        iterator.next();
        // 分割后的第二段代码
        iterator.next();
        iterator.next();
    </script>
</body>

</html>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值