• ES6深入(Symbol、类、迭代器、Set、Map)(二)


    系列文章目录

    第一章:ES6基础语法(let、const、解构赋值、模板字符串、简化对象、箭头函数、扩展运算符)(一)
    第三章:ES6深入(生成器、Promise、async/await)(三)
    第四章:ES6+新增API拓展(对象API拓展、数组API拓展、字符串&函数API拓展、数值API拓展)(四)



    一、Symbol 基本使用

    ES6 引入了一种新的基本数据类型 Symbol,表示独一无二的值。是一种类似于字符串的数据类型。

    Symbol 特点

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

    案例:

    1.创建Symbol值

    let sy1 = Symbol("myname");
    
    console.log(sy1, typeof Symbol);//Symbol(myname) function
    let sy2 = Symbol("myage");
    
    console.log(sy1 === sy2);//false
    
     //不能与其他数据进行运算
    //    let result = s + 100;
    //    let result = s > 100;
    //    let result = s + s;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.Symbol创建对象属性

     let game = {}
    
     let methods = {
    			//声明一个对象
                up: Symbol("hh"),
                down: Symbol("123")
            };
            game[methods.up] = function () {
                console.log("我可以改变形状");
            }
            game[methods.down] = function () {
                console.log("我可以快速下降!!");
            }
            console.log(game);
            let youxi = {
                name: "狼人杀",
                [Symbol('say')]: function () {
                    console.log("我可以发言")
                },
                [Symbol('zibao')]: function () {
                    console.log('我可以自爆');
                }
            }
            console.log(youxi)
            //静态方法
    		let res = Object.getOwnPropertySymbols(youxi);
    		console.log(youxi[res[1]])//[Function: [zibao]]
    		
    		
    		for (let key in youxi) {
    		 	console.log(key)//name
    		 }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    运行结果:
    在这里插入图片描述
    3.全局注册表

    Symbol.for() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了。假如是,则会直接返回上次存储的那个。否则,它会再新建一个。

    let sy1 = Symbol('hello');
    let sy2 = Symbol("hello");
    console.log(sy1 === sy2);
    
    // Symbol.for()
    let sy3 = Symbol.for('hello');
    let sy4 = Symbol.for("hello");
    console.log(sy3 === sy4)
    
    //Symbol.keyFor()可以检测symbol值是否在全局注册表中注册过。 返回对于symbol的描述或者undefined
    console.log(Symbol.keyFor(sy1))
    console.log(Symbol.keyFor(sy3))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:
    在这里插入图片描述

    二、Class

    ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

    1.class 声明类 ,constructor 定义构造函数初始化

    代码示例:

    		//ES5
            function Phone(brand, price) {
                this.brand = brand;
                this.price = price;
            }
            Phone.prototype.call = function() {
                console.log("打电话!!!");
            }
            let Huawei = new Phone('华为', 5999);
            Huawei.call();
            console.log(Huawei);
            //ES6
            class Shouji {
            // 类的构造器 ---必须提供 如果不写默认 提供空的构造器
                constructor(brand, price) {
                	// 实例私有属性
                    this.brand = brand;
                    this.price = price;
                }
                // 实例公共方法--类似于存在于原型对象中Person.prototype
                call() {
                    console.log('dianhua')
                }
            }
            let onePlus = new Shouji("1+", 10000);
            onePlus.call();
            console.log(onePlus);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    运行结果:
    在这里插入图片描述
    2. extends 继承父类

    代码示例:

    //ES5方法
    function Phone(brand, price) {
        this.brand = brand;
        this.price = price
    }
    Phone.prototype.call = function() {
        console.log("我可以打电话!!!");
    }
    //智能手机
    function SmartPhone(brand, price, color, size) {
        Phone.call(this, brand, price);
        this.color = color;
        this.size = size;
    }
    //设置子级构造函数的原型
    SmartPhone.prototype = new Phone();
    SmartPhone.prototype.constructor = SmartPhone;
    //声明子类的方法
    SmartPhone.prototype.photo = function() {
        console.log("我可以拍照")
    }
    SmartPhone.prototype.playGame = function() {
        console.log("我可以玩游戏");
    }
    const huawei = new SmartPhone("华为", 2333, "蓝色", "5.5寸");
    console.log(huawei);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    运行结果:

    在这里插入图片描述

    //ES6
    class Phone {
                constructor(brand, price) {
                    this.brand = brand;
                    this.price = price
                }
                call() {
                    console.log("打电话");
                }
            }
            class SmartPhone extends Phone {
                constructor(brand, price, color, size) {
                    super(brand, price);// Phone.call(this, brand, price)
                    this.color = color;
                    this.size = size;
                }
                //super 调用父级构造方法
                 call() {
                    super.call()
                    console.log('我可以进行视频通话');
                }
                photo() {
                    console.log("拍照");
                }
                playGame() {
                    console.log("玩游戏");
                }
            }
            const huawei = new SmartPhone("华为", 2333, "蓝色", "5.5寸");
            console.log(huawei);
            // 继承
    		// 1.子类的原型对象通过一个指针继承父类的原型对象
    		console.log(SmartPhone.prototype.__proto__ == Phone.prototype);
    		// 2.子类对象通过一个指针指向父类对象继承
    		console.log(SmartPhone.__proto__ == Phone);
    		console.log(huawei.__proto__ == SmartPhone.prototype);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    结果:
    在这里插入图片描述
    3.static 定义静态方法和属性 --属于类不属于实例对象
    通过static关键字定义静态属性和静态方法。也可以在外侧添加静态属性;静态属性和静态方法是定义在类【构造函数】上的,所以可以通过类【构造函数】直接访问。在静态方法中,this指向当前类【构造函数】

    代码示例:

    class Phone {
    			// 静态属性 由static 声明的属性就是静态属性
                static name = '手机'
                // 静态方法 由static声明的静态方法
                static change() {
                    console.log("改变世界!!!");
                }
            }
            // console.log(Phone.name);
            let nokia = new Phone();
            console.log(nokia.name);//报错
            console.log(Phone.name);//手机
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:
    在这里插入图片描述

    三、迭代器

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

    Iterator 的作用有三个: 一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费。

    原生具备 iterator 接口的数据(可用 for of 遍历)

    1. Array 2) Arguments 3) Set 4) Map 5) String 6) TypedArray 7)NodeList

    案例:

    // 返回什么 返回迭代器对象 
    let [a] = '10'; //字符串实现了迭代器接口 就可以使用for ...of遍历
    console.log(a);
    let str = 'hello';
    for (let k of str) {
        console.log(k);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行结果:
    在这里插入图片描述

    Iterator工作原理(遍历过程是这样的)

    1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

    2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

    3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

    4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

    拓展: for-of实现原理就是调用迭代器的next()方法,第一次调用将指针指向数据结构的第一个成员,依次调用依次指向,直到没有成员可以指向,done为true

    案例:

    
    let arr = [1, 2, 3, 'hello'];
    let keys = arr.keys(); //迭代器对象 
    let values = arr.values(); //迭代器对象 for  of 数组元素
    let entries = arr.entries();
    // 手动调用next  遍历迭代器对象  {value:0 ,done:false}
    let result;
    while (!(result = values.next()).done) {
        console.log(result);
    }
    // 运行结果
    // { value: 1, done: false }
    // { value: 2, done: false }
    // { value: 3, done: false }
    // { value: 'hello', done: false }
    console.log("----------------")
    
    console.log(keys.next()); //{ value: 0, done: false } done为false表示不是最后成员
    console.log(keys.next()); //{ value: 1, done: false } done为false表示不是最后成员
    console.log(keys.next()); //{ value: 2, done: false } done为false表示不是最后成员
    console.log(keys.next()); //{ value: 3, done: false } done为false表示不是最后成员
    console.log(keys.next()); //{ value: undefined, done: true }
    console.log("----------------")
    
    console.log(values.next()); //{ value: 1, done: false }
    console.log(values.next()); //{ value: 2, done: false }
    console.log(values.next()); //{ value: 3, done: false }
    console.log(values.next()); //{ value:'hello', done: false }
    console.log(values.next()); //{ value: undefined, done: true }
    console.log("----------------")
    
    
    // console.log(entries.next());
    for (let k of entries) {
        // keys  k  ---下标
        // values k--数组元素
        // entries k-下标和数组元素组成得数组
        console.log(k);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    运行结果:
    在这里插入图片描述

    四、Set

    ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,它可以接收一个数组作为参数
    集合的属性和方法:

    1. size
      返回集合的元素个数
    2. add
      增加一个新元素,返回当前集合
    3. delete 删除元素,返回 boolean 值
    4. has
      检测集合中是否包含某个元素,返回 boolean 值
    5. clear
      清空集合,返回 undefined

    案例:

    // 概念:es6提供新的数据结构 类似于数组 成员是唯一得 没有重复得值
    // key和value是一样得
    // 创建一个set数据结构 
    let set = new Set();
    // set api 
    // 1.添加成员
    set.add('tom');
    set.add('jack');
    set.add('jack');
    set.add([1]);
    set.add([1]);
    // console.log(set.size,set);
    // 使用add方法添加基本数据类型成员 会做自动去重
    // 使用add方法添加引用数据类型成员 全部添加 
    // 删除成员
    
    console.log(set);
    set.delete('tom');
    console.log(set);
    console.log("-----------")
        // 查看set长度  size属性
        // 遍历set 
    console.log(set.keys());
    console.log(set.values());
    console.log(set.entries());
    console.log("-----------")
    
    for (let k of set.keys()) {
        console.log(k);
    }
    console.log("-----------")
    
    let res = set.forEach((key, value, set) => {
        console.log(key, value, set);
    });
    
    console.log(res);
    console.log("-----------")
    
    // 查看有没有某一个成员 has(key/value)
    // 返回 或者false值:true
    console.log(set.has('tom'));
    console.log(set.has('jack'));
    
    console.log("-----------")
    
    // 清空全部set成员  参数 无参 返回值 清空后set
    set.clear();
    console.log(set);
    console.log("-----------")
    
    // 应用 去重数组
    // es5 项目中 slice filter map 
    console.log([...new Set([1, 2, 3, 2, 1])]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    运行结果:
    在这里插入图片描述

    五、Map

    ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
    Map 的属性和方法:

    1. size
      返回 Map 的元素个数
    2. set
      增加一个新元素,返回当前 Map
    3. get
      返回键名对象的键值
    4. has
      检测 Map 中是否包含某个元素,返回 boolean 值
    5. clear
      清空集合,返回 undefined

    案例:

    // 概念:类似于对象 是一种集合 键值对组成得数据结构 键可以是任意数据类型
    // 对象 键只能是字符串或者是symbol值
    let obj = {
        name: 'zhangsan',
        age: 12
    };
    // console.log(obj,typeof obj[1]);
    let res = Object.entries(obj);
    // 创建一个map集合 构造函数
    // 购物车 - +
    // [] map
    console.log(res)
    let map = new Map(res);
    console.log(map);
    console.log("--------------");
    
    // 给map添加成员
    let temp = [123];
    map.set(temp, 'hello');
    console.log(map);
    console.log("--------------");
    
    // // 删除map成员
    map.delete(temp);
    console.log(map);
    console.log("--------------");
    
    // delete 可以直接删除基本数据类型得键 
    // 删除引用数据类型需要删除引用地址 
    // 遍历方法
    console.log(map.keys());
    console.log(map.values());
    console.log(map.entries());
    console.log("--------------");
    
    for (let k of map.keys()) {
        console.log(k, '1111');
    }
    console.log("--------------");
    
    let result = map.forEach((value, key, map) => {
        console.log(value, key, map);
    });
    console.log("--------------");
    
    // 获取map属性
    console.log(map.get(temp));
    
    for (let k of map) {
        console.log(k);
    }
    
    console.log(map.__proto__);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    运行结果:

    在这里插入图片描述
    map和object区别?

    1.map得键可以是任意数据类型,object得键只能是字符串或者symbol
    2.map是一个可迭代得数据结构 对象不可以直接迭代
    3.map可以通过size属性获取数据结构长度 对象不可以直接获取
    4.map循环遍历按照顺序进行输出 对象属性无序数据结构

  • 相关阅读:
    ubuntu20.04搭建janus服务器
    Http不转换成Https会有什么后果?
    GitLab忘记管理员密码处理和禁用注册功能
    5G专网融合时间敏感网络架构技术
    Linux 文件系统(一) --- ext4文件系统简介
    反射技巧让你的性能提升 N 倍
    常见排序算法之插入排序类
    如何在几百万qps的网关服务中实现灵活调度策略
    Nginx的核心配置文件
    什么是IP防护等级,又该如何区分
  • 原文地址:https://blog.csdn.net/qq_48617322/article/details/126920722