【ES6】扩展运算符、symbol、迭代器

94 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

扩展运算符

【代码示例】

...扩展运算符能将数组转换为逗号分隔的参数序列

未使用扩展运算符时

	const fruits = ["西瓜", "草莓", "芒果"];
    function data() {
        console.log(arguments);
    }
    data(fruits)

在这里插入图片描述 使用扩展运算符

    const fruits = ["西瓜", "草莓", "芒果"];
    function data() {
        console.log(arguments);
    }
    data(...fruits)

在这里插入图片描述

【扩展运算符应用】

//1. 数组的合并
    const kuaizi = ['王太利','肖央'];
    const fenghuang = ['曾毅','玲花'];
    // 传统的合并方式
    //const mix = kuaizi.concat(fenghuang)
    const mix = [...kuaizi,...fenghuang]
    console.log(mix);//['王太利', '肖央', '曾毅', '玲花']

    //2. 数组的克隆
    const songs = ['小苹果','老男孩','小水果'];
    const songs2 = [...songs];
    console.log(songs2);//['小苹果','老男孩','小水果']

    //3. 将伪数组转为真正的数组
    const divs = document.querySelectorAll('div');//获取到的是object
    const divArr = [...divs];//转为了数组,可以用数组的相关方法了
    console.log(divArr);

symbol

【概述】

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型

【特点】

  1. Symbol 的值是唯一的,用来解决命名冲突的问题
  2. Symbol 值不能与其他数据进行运算
  3. Symbol 定义的对象属性不能使用for…in循环遍历 ,但是可以使用Reflect.ownKeys 来获取对象的所有键名

【代码示例】

//创建Symbol
    let s = Symbol();
    console.log(s, typeof s);//Symbol() 'symbol'
    let s2 = Symbol('张三');
    let s3 = Symbol('张三');
    console.log(s2 === s3); // false
    //Symbol.for 创建
    let s4 = Symbol.for('张三');
    let s5 = Symbol.for('张三');
    console.log(s4===s5); // true

    //不能与其他数据进行运算
    // let result = s + 100;
    // let result = s > 100;
    // let result = s + s;

    //js 中的数据类型
    // USONB you are so niubility
    // u undefined
    // s string symbol
    // o object
    // n null number
    // b boolean

【Symbol创建对象属性】

	 // 向对象中添加方法 up down
    let game = {
        name: '俄罗斯方块',
        up: function () {
        },
        down: function () {
        }
    };

    // 现在需要向game对象里面添加方法,为避免game对象已存在同名方法,这时使用Symbol
    // 方式一
    // 声明一个对象
    let methods = {
        up: Symbol(),
        down: Symbol()
    };
    game[methods.up] = function () {
        console.log("上升上升");
    }
    game[methods.down] = function () {
        console.log("下降下降");
    }
    console.log(game);
	//方法调用
    game[methods.up]();
    
    // 方式二
    let youxi = {
        name: "狼人杀",
        [Symbol('say')]: function () {
            console.log("我可以发言")
        },
        [Symbol('zibao')]: function () {
            console.log('我可以自爆');
        }
    }
    console.log(youxi);

在这里插入图片描述

【symbol内置属性】

除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行

symbol内置值调用时机
Symbol.hasInstance当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开
Symbol.species创建衍生对象时,会使用该属性
Symbol.match当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值
Symbol.replace当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值
Symbol.search当该对象被 str. search (myObject)方法调用时,会返回该方法的返回值
Symbol.split当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值
Symbol.iterator对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值
Symbol. toStringTag在该对象上面调用 toString 方法时,返回该方法的返回值
Symbol. unscopables该对象指定了使用 with 关键字时,哪些属性会被 with环境排除
class Person {
        static [Symbol.hasInstance](param) {
            console.log(param);//{}
            console.log("我被用来检测类型了");//我被用来检测类型了
            return false;
        }
    }

    let o = {};
    console.log(o instanceof Person);//false
    const arr = [1, 2, 3];
    const arr2 = [4, 5, 6];
    // 合并数组:false数组不可展开,true可展开
    arr2[Symbol.isConcatSpreadable] = false;
    console.log(arr.concat(arr2));//(4)[1, 2, 3, Array(3)]

在这里插入图片描述

迭代器

【概述】

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作

【特性】

ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费; 原生具备 iterator 接口的数据(可用 for of 遍历):

  • Array;
  • Arguments;
  • Set;
  • Map;
  • String;
  • TypedArray;
  • NodeList;

【示例代码】

       var arr=[0,1,2,3];
       for(let v of arr){
           console.log(v)
       }

       var arr = ['唐僧','孙悟空','猪八戒','沙僧'];
       for(var item of arr){
           console.log(item);
       }

在这里插入图片描述

【工作原理】

  1. 创建一个指针对象,指向当前数据结构的起始位置;
  2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
  3. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
  4. 每调用 next 方法返回一个包含 value 和 done 属性的对象; 注:需要自定义遍历数据的时候,要想到迭代器;
// 声明一个数组
    const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧'];

    let iterator = xiyou[Symbol.iterator]();
    // 调用对象的next方法
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());

在这里插入图片描述

【迭代器自定义遍历对象】

// 声明一个对象
    const banji = {
        name: "终极一班",
        stus: [
            'xiaoming',
            'xiaoning',
            'xiaotian',
            'knight'
        ],
        [Symbol.iterator]() {
            // 索引变量
            let index = 0;
            // 保存this
            let _this = this;
            return {
                next: function () {
                    if (index < _this.stus.length) {
                        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);
    }

在这里插入图片描述