【ES6知识】Iterator迭代器与 class类

2023-09-19 09:09:24

一、Iterator迭代器

1.1 基础知识概述

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

ES6创造了一种新的遍历命令:for…of 循环,Iterator 主要供 for…of 使用。

原生JavaScipt案例合集
JavaScript +DOM基础
JavaScript 基础到高级
Canvas游戏开发

原生具备了 Iterator 接口的数据结构:

  • Array 数组
  • TypedArray 定型数组(一类指定元素类型的数组,不是实际的数组类型。创建的实例将在内存中创建一个数组缓冲区)
  • String 字符串
  • Arguments 参数(实参)对象
  • NodeList 节点列表
  • Set 数据结构
  • Map 数据结构

在这里插入图片描述

var arr = [1,2,3,4];
let iterator = arr[Symbol.iterator]();
 
console.log(iterator.next());  //{ value: 1, done: false }
console.log(iterator.next());  //{ value: 2, done: false }
console.log(iterator.next());  //{ value: 3, done: false }
console.log(iterator.next());  //{ value: 4, done: false }
console.log(iterator.next());  //{ value: undefined, done: true }

1.2 工作原理

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
  3. 接下来不断调用 next 方法,指针一直往后移,直到指向最后一个成员
  4. 每次调用 next 方法,返回一个包含 value 和 done 属性的对象
let obj = {
    name:"张三",
    age:18,
    arr:[1,2,3,4,"壹","贰","叁","肆"]
}

现在想要拿到 obj 对象中 arr 数组的数据。由于 Object 并没有内置 Iterator ,所以使用 for…of 遍历时,控制台报错。

let obj = {
    name:"张三",
    age:18,
    arr:[1,2,3,4,"壹","贰","叁","肆"]
}
for(value of obj){
    console.log(value)
}
//Uncaught TypeError: obj is not iterable

至于对象没有布置 iterator 接口的原因,不知道大家有没有看根据《你一生的故事》拍成的电影“降临",片中出现的外星语言是一门非线性的语言。而我们说的数组,Map 等结构中的成员都是有顺序的,即都是线性的结构,而对象,各成员并没有一个确定的顺序,所以遍历时先遍历谁后遍历谁并不确定。所以,给一个对象部署 iterator 接口,其实就是对该对象做一种线性转换。如果你有这种需要,就需要手动给你的对象部署 iterator 接口。如下:

let obj = {
    name:"张三",
    age:18,
    arr:[1,2,3,4,"壹","贰","叁","肆"],
    [Symbol.iterator](){
        let index =0
        let _this = this
          return {
             next:function(){
                 if(index < _this.arr.length){
                      return { value:_this.arr[index++], done:false}      
                 }else{
                    return {value:undefined,done:true}
                 }
          	}
        }
    }
}
for(value of obj){
  console.log(value)
}
//1 2 3 4 "壹" "贰" "叁" "肆"

可以看到,Symbol.iterator会返回一个对象,这就是一个遍历器对象,而作为遍历器对象,其必须具备的特征就是必须具备next()方法。

1.3 Symbol.iterator

在这里插入图片描述

这个符号可以是任意对象上的一个专门属性,语言机制会自动的在这个属性上寻找一个方法,这个方法会构造一个迭代器来迭代这个对象的值,这个方法就是 next 方法,… 展开和 for/of 循环会自动使用它,**我们可以自定义 Symbol.iterator 属性为任意对象值定义自己的迭代器逻辑,它将覆盖默认的迭代器。**相当于定义了一种元编程行为,提供给 Javascript 其他部分(运算符和循环结构)在处理定义的对象时使用。

  • 在 JS 中迭代器对象实现了可迭代协议,迭代器对象由 Symbol.iterator 属性的值返回。
  • Symbol.iterator 属性的值是一个函数,它返回一个迭代器对象。
  • 迭代器指的是拥有 next 方法的对象。
  • 该next方法必须返回一个带有 value 和 done 的对象。

1.4 Generator函数来实现Symbol.iterator接口

var yieldIterator = {};
yieldIterator[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
 
[...yieldIterator] // [1, 2, 3]

注意,yield* 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。

其它调用到遍历器的操作还有解构赋值、扩展操作符、其它任何接受数组作为参数的场合

  • for…of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如)
  • Promise.all()
  • Promise.race()

一旦当你给你的结构部署了iterator接口,那么恭喜你,你可以使用for…of来遍历你的结构了!

二、ES6 Class 类

2.1 概述

ES6之前,类和构造函数是同一个东西,并且调用的函数需要外挂(通过构造函数调用原型进行定义)。这对于面向对象语言很不友好,所以ES6中提供了类的概念。

  • class类、constructor构造器区别开来
  • class类中直接定义方法(原型方法、静态方法、实例方法)
class People {
    // 静态方法
    static sayHello(){
        return "Hello ES6继承!!";
    }

    // 通过 constructor 定义类的构造函数
    constructor(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;

        // 实例方法
        this.sayHi = function(){
            return "你好"
        }
    }

    // 原型方法,不需要 function 声明
    eat() {
        return "是人就得喝水...";
    }
}

// 通过 new 关键子定义一个类的对象
var p = new People("汉武帝", 1000, '男');

2.2 ES6中的继承

  • extends 用于继承的关键字
  • super 用于执行父类(超类、基类)中的构造函数
// 通过关键字 class 定义基类
class People {
    // 静态方法
    static sayHello(){
        return "Hello ES6继承!!";
    }

    // 通过 constructor 定义类的构造函数
    constructor(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;

        // 实例方法
        this.sayHi = function(){
            return "你好"
        }
    }

    // 原型方法,不需要 function 声明
    eat() {
        return "是人就得喝水...";
    }
}


class Doctor extends People {
    constructor(name, age, sex, clothes) {
        super(name, age, sex);

        this.clothes = clothes;
    }

    behavior() {
        return "救死扶伤";
    }
}

// 通过 new 关键子定义一个类的对象
var p = new People("汉武帝", 1000, '男');
var d = new Doctor("李时珍", 700, '男', '白大褂');

2.3 面向对象应用 - React

  • 组件化 - class

  • JSX(JS拓展版) == babel == browser.js

  • 下载 react.js , react-dom.js,browser.js ,并引入到项目中

  • script 标签类型 type = “text/babel”,且不可以省略

HTML代码:

<div id="div1"></div>

JS代码:

<script src="./libs/react.js"></script>
<script src="./libs/react-dom.js"></script>
<script src="./libs/browser.js"></script>
<script type="text/babel">
	// 自定义组件
	class Item extends React.Component{
		constructor(...args){
			super(...args)
		}
		
		render(){
			// 返回固定的值
			// return <li>123</li>
			// 返回通过属性动态传递的值
			return <li>{this.props.str}</li>
		}
	}
	
	class List extends React.Component{
		constructor(...args){
			super(...args)
		}
		
		render(){
		  	/*
		  	let aItems = [];
			for(let i = 0; i < this.props.arr.length; i++){
				aItems.push(<Item str={this.props.arr[i]}></Item>)
			}
			return <ul>
				// 数组映射
				{aItems}
			</ul>
			*/
			
			// map 优化
			let aItems = this.props.arr.map(a => <Item str={a}></Item>);
			/*			
			return <ul>
				{this.props.arr.map(a => <Item str={a}></Item>)}
			</ul>
			*/
			return <ul>
				{aItems}
			</ul>
		}
	}
	
	window.onload = function(){
		let oDiv = document.getElementById('div1');
		
		ReactDOM.render(
			// 常规标签渲染
			// <span>123</span>,
			// 自定义组件渲染
			<List arr="{['abc','def',ghi]}"></List>,
			oDiv
		)
	}
</script>
更多推荐

DC电源模块具有不同的安装方式和安全规范

BOSHIDADC电源模块具有不同的安装方式和安全规范DC电源模块是将低压直流电转换为需要的输出电压的装置。它们广泛应用于各种领域和行业,如通信、医疗、工业、家用电器等。安装DC电源模块应严格按照相关的安全规范进行,以确保其正常运行和安全使用。DC电源模块的安装方式主要有固定式和可调式两种。固定式DC电源模块的输出电压

Tomcat服务启动失败:java.lang.OutOfMemoryError: Java heap space

具体报错:java.lang.OutOfMemoryError:Javaheapspace报错分析:这个报错表明Java程序运行时内存不足。Tomcat服务在启动时需要占用一定的内存资源,如果分配的内存不足,就会出现该错误。通常情况下,出现该错误的原因是JVM的堆内存大小不足以支持Tomcat服务的启动。报错解决过程:

数据库设计-----理论

1.2数据库基本概念1、关系:两个表的公共字段2、行:也称记录,也称实体3、列:也称字段,也称属性就表结构而言,表分为行和列;就表数据而言,分为记录和字段;就面向对象而言,一个记录就是一个实体,一个字段就是一个属性。4、数据冗余:相同的数据存储在不同的地方脚下留心:1、冗余只能减少,不能杜绝。2、减少冗余的方法是分表3

Linux服务器初始化、yum安装java、redis、mysql

目录前言一、yum安装java二、yum安装redis三、yum安装mysql前言本文使用yum命令安装部署可能会用到的相关应用安装软件包之前,我们需要先更新系统,以确保安装的软件包是最新的版本。执行以下命令:sudoyumupdate一、yum安装java1、查看可安装版本yum-ylistjava*2、安装1.8版

redis的安装和配置

文章目录1.安装Redis1.1依赖库1.2上传安装包并解压2启动Redis2.1默认启动2.2指定配置启动2.3开机自启3Redis桌面客户端3.1Redis命令行客户端3.2图形化桌面客户端3.2.1安装3.2.2建立连接1.安装Redis大多数企业都是基于Linux服务器来部署项目,而且Redis官方也没有提供W

红队打靶:Me and My Girlfriend打靶思路详解(vulnhub)

目录写在开头第一步:主机发现和端口扫描第二步:Web渗透(修改XFF代理)第三步:数据库手工枚举第四步:sudophp提权总结与思考写在开头本篇博客在自己的理解之上根据大佬红队笔记的视频进行打靶,详述了打靶的每一步思路,并非复现writeup,读者耐心看完,定会有所收获。MeandMyGirlfriend这个靶机是近期

《Java8实战》

《Java实战》学习整理文章目录一、Lambda1.1基础概念1.1.1[Lambda表达式](https://baike.baidu.com/item/Lambda表达式/4585794?fromModule=lemma_inlink)定义1.2引入Lambda1.3Lambda1.3.1函数式接口1.3.2Lamb

pyecharts可视化

pyecharts是基于Echarts图表的一个类库Echarts是百度开源的一个可视化JavaScript库一、pyecharts简介pyecharts主要基于web浏览器进行显示,绘制图形(有折线图、柱状图、饼图、漏斗图、地图及极坐标图等)安装pipinstallpyecharts二、pyecharts的使用方法绘

jmeter生成html格式接口自动化测试报告

jmeter自带执行结果查看的插件,但是需要在jmeter工具中才能查看,如果要向领导提交测试结果,不够方便直观。笔者刚做了这方面的尝试,总结出来分享给大家。这里需要用到ant来执行测试用例并生成HTML格式测试报告。一、ant下载安装1.1、下载地址:http://ant.apache.org/bindownload

计算机网络运维方向综合知识大全

一.基础知识1.网络的组成组成部分:硬件、软件、协议硬件主要由主机(也称端系统)、通信链路(如双绞线、光纤)、交换设备(如路由器、交换机等)和通信处理机(如网卡)等组成。软件主要包括各种实现资源共享的软件和方便用户使用的各种工具软件(如网络操作系统、邮件收发程序、FTP程序、聊天程序等)。软件部分多属于应用层。协议是计

Mac中IntelliJ IDEA每次打开立刻“意外退出”的解决方法

本文介绍在Mac电脑中,无法打开IntelliJIDEA软件,出现“意外退出”的报错提示,且重启软件依然出现这一情况的通用解决思路与方法。最近,不知道怎么回事,点击图标准备打开IntelliJIDEA软件时,很快就会出现”IntelliJIDEA“意外退出。的提示,如下图所示。且无论怎么样重复打开IntelliJIDE

热文推荐