JavaScript ES6新增语法相关个人总结(二)_let res 语法-程序员宅基地

技术标签: html5  前端  es6  js  Work-JavaScript  javascript  

第7种数据类型,Symbol

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

- 代码例:

// 创建Symbol
let s = Symbol()
console.log(s, typeof s) // Symbol()  'symbol'

// 创建Symbol时写入名称,相当于注释名
let s2 = Symbol('name')
let s3 = Symbol('name')
console.log(s2 === s3) // false,每个symbol都是唯一的,不会完全相等

// Symbol.for创建
let s4 = Symbol.for('age')
let s5 = Symbol.for('age')
console.log(s4 === s5) // true,Symbol.for创建的,只要其中的标识值相同,例:'age',那么被创建的symbol就完全相等

// 创建的symbol不能进行运算,以下操作都会报错
let res1 = s + 100
let res2 = s > 100
let res3 = s + '你好'

- Symbol创建对象属性

- 代码例:

let obj = {
    ...}

// 在不知道以上对象中含有哪些属性时,使用Symbol对其创建属性
// 可以保证绝对的唯一性,且不会对原本对象里的属性造成影响
// 方法1
let methods = {
    
  fn: Symbol(),
  fn2: Symbol()
}
obj[methods.fn] = function() {
    
  console.log('fn()')
}
obj[methods.fn2] = function() {
    
  console.log('fn2()')
}

// 方法2
let obj2 = {
    
  name: 'sky',
  [Symbol('fn')]: function(){
    
	console.log('fn()')
  },
  [Symbol('fn2')]: function(){
    
	console.log('fn2()')
  }
}

- Symbol内置的值

Symbol内置了11种值,这些值指向语言内部使用的方法,不同的方法会在特定的场景下自动执行。

方法名 说明
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环境排除。

迭代器,for…of

- 基本使用及实现原理

- 代码例:

// 声明数组
const arr = ['sky', 'tom', 'jack', 'joe']

// for...in
for(let i in arr){
    
  console.log(i) // 返回数组索引下标,依次输出 0 1 2 3
}

// for...of
for(let j of arr){
    
  console.log(j) // 返回数组内的每个值,依次输出 'sky' 'tom' 'jack' 'joe'
}

对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器

实现原理:

  • 创建一个指针对象,指向当前数据结构的起始位置
  • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
  • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
  • 每调用 next 方法返回一个包含 value 和 done 属性的对象

- 代码例:

// 声明数组
const arr = ['sky', 'tom', 'jack', 'joe']

// arr数组有个Symbol.iterator方法,我们用一个变量来接收这个方法的返回结果
let iterator = arr[Symbol.iterator]()

// 而这个返回对象内,有个next方法
// 执行该方法会依次指向该数据结构内的成员,返回一个包含value和done属性的对象
console.log(iterator.next()) // {value: 'sky', done: false}
console.log(iterator.next()) // {value: 'tom', done: false}
console.log(iterator.next()) // {value: 'jack', done: false}
console.log(iterator.next()) // {value: 'joe', done: false}
console.log(iterator.next()) // {value: undefined, done: true}

- 使用迭代器自定义遍历对象

- 代码例:

// 创建一个对象,包含数组
const obj1 = {
    
  name: 'sky',
  arr: ['joe', 'tom', 'jack', 'bob']
}
// 遍历该对象
for(let i of obj1){
    
  console.log(i)
}

// 由于for...of遍历的是数组,无法直接遍历对象,因此以上代码会报错
// 我们需要在该对象中自定义需要遍历的数组,才能遍历返回正确结果

// 创建一个对象,包含数组
const obj2 = {
    
  name: 'sky',
  arr: ['joe', 'tom', 'jack', 'bob'],
  // 在需要遍历的对象内,自定义创建Symbol.iterator方法
  [Symbol.iterator]() {
    
    // this指向
    let _this = this
	// index索引变量
	let index = 0
	// 需要遍历的数组长度
	let length = this.arr.length
    // Symbol.iterator方法内会返回一个对象
	return{
    
	  // 返回对象内包含一个next方法
	  next(){
    
	  	// next方法内自定义需要遍历的数组对象
	  	if(index < length){
    
	  	  // next 方法返回一个包含 value 和 done 属性的对象
	  	  const result = {
    value: _this.arr[index], done: false}
	  	  // index自增
	  	  index++
	  	  // 返回对象
	  	  return result
	  	}else{
    
	  	  return {
    value: undefined, done: true}
	  	}
	  }
	}
  }
  
}
// 遍历该对象
for(let j of obj2){
    
  console.log(j)  // 返回对象内arr数组的值,依次输出 'joe', 'tom', 'jack', 'bob'
}

生成器函数

生成器就是一个特殊的函数

- 代码例:

// 创建一个生成器函数,*号靠左靠右都没关系
function * gen(){
    
  console.log('hello')
}
// 直接执行该函数,内部语句是不执行的
gen()
// 生成器函数的返回结果就是一个迭代器对象
let iterator = gen()
// 用其中的next方法才能运行语句
console.log(iterator.next()) // 'hello'

// yield分隔符,可以用来控制分隔每次执行next方法时,所需要执行的语句
function * gen2(){
    
  console.log(111) // 第一次next方法执行的语句
  yield '第一段执行完毕'
  console.log(222) // 第二次next方法执行的语句
  yield '第二段执行完毕'
  console.log(333) // 第三次next方法执行的语句
  yield '第三段执行完毕,还有最后一段未执行'
  console.log(444) // 第四次next方法执行的语句
}

let iterator2 = gen2()
console.log(iterator2.next()) // {value: '第一段执行完毕', done: false}
console.log(iterator2.next()) // {value: '第二段执行完毕', done: false}
console.log(iterator2.next()) // {value: '第三段执行完毕', done: false}
console.log(iterator2.next()) // {value: undefined, done: true}

- 生成器函数传参

- 代码例:

// 创建生成器函数
function * gen(arg){
    
  console.log(arg) // 'gen执行时的参数'
  // 创建变量,接收next方法内的实参
  let next2Arg = yield 1
  console.log(next2Arg) // '第2次next的参数'
  let next3Arg = yield 2
  console.log(next3Arg) // '第3次next的参数'
  let next4Arg = yield 3
  console.log(next4Arg) // '第4次next的参数'
}

let iterator = gen('gen执行时的参数')
iterator.next()
// 第2次next方法开始可以传入实参
// 该实参由当前next方法所执行语句的前一个yield所接受
iterator.next('第2次next的参数')
iterator.next('第3次next的参数')
iterator.next('第4次next的参数')

- 生成器函数-模拟请求数据

- 代码例:

// 请求用户数据
function getUsers() {
    
  setTimeout(()=>{
    
    let data = '用户数据'
    // 传入用户数据,执行下个next
    iterator.next(data)
  },1000)
}

// 请求订单数据
function getOrders() {
    
  setTimeout(()=>{
    
    console.log(users) // '用户数据'
    let data = '订单数据'
    // 传入订单数据,执行下个next
    iterator.next(data)
  },1000)
}

// 请求商品数据
function getGoods() {
    
  setTimeout(()=>{
    
    console.log(orders) // '订单数据'
    let data = '商品数据'
    // 传入商品数据,执行下个next
    iterator.next(data)
  },1000)
}

// 创建生成器函数
function * gen() {
    
  // users 用户数据实参
  let users = yield getUsers()
  // orders 订单数据实参
  let orders = yield getOrders()
  // goods 商品数据实参
  let goods = yield getGoods()
}

// 创建迭代器对象并调用next
let iterator = gen()
iterator.next()


- Recorded by Scorpio_sky@2021-01-17

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Scorpio_sky/article/details/112709040

智能推荐

与众不同的Java_special jiva actualiser of awareness-程序员宅基地

文章浏览阅读75次。Java与世界的初次见面——Java产生史故事版 2021年的一天,这为29岁的工程师回到家中,放下手中的各种工具,静静地躺在贵妃榻上,望着窗外远方的山,端起手边的咖啡微抿一口,思绪又渐渐回到了30年前。那时的他刚刚出生,但根据这个世界的规定,未满三岁的新生儿不能够登记并拥有自己的名字,于是父母便临时给它起了一个名字叫Oak。Oak从小就要与众不同,他常常用自己与众不同的方法解决前辈们所处的各种问题,但就算如此,他依然没有得到前辈们的重视,只是像同辈们一样,渐渐长到了3岁,而就在他三岁的这..._special jiva actualiser of awareness

kepserver在设备上添加项目失败_隔空投送存储项目失败怎么办-程序员宅基地

文章浏览阅读1.5k次。iphone隔空投送失败是什么原因?IOS系统下有两个并列又超级强大的功能就是Airplay屏幕镜像与AirDrop隔空投送,Airplay屏幕镜像,其实经常玩手机投屏的水果粉应该都知道,Airplay屏幕镜像可以进行多屏幕之间的一个互动功能,播放模式为镜像模式,也就是手机与投屏的大屏幕为同步显示状态。AirDrop隔空投送:(推荐学习:web前端视频教程)AirDrop是Apple在设备之间以无..._kepserver尝试添加项''失败

fine-tune 微调 Transfer learning 迁移学习 动手学深度学习v2_finetune——transfer-程序员宅基地

文章浏览阅读398次。1. Fine-tuning 微调 Transfer learningFine-tuning 微调是整个深度学习领域是最重要的技能。如果前面的知识只能选择一个,那就是微调了。Transfer learning迁移学习,就是可以用别的成功网络的参数等来训练跟你相似的模型。简单来说是重用。跟详细知识请参考: Transfer learning 迁移学习指南2. 代码实现3. Q&Afine tuning和transfer training实际上是同_finetune——transfer

python使用docx对齐表格_Python docx库文本对齐-程序员宅基地

文章浏览阅读1.7k次。我正在使用python docx库来操作word文档.但是我找不到该库的文档页面中的一条线与中心对齐.我也找不到Google.from docx import Documentdocument = Document()p = document.add_paragraph('A plain paragraph having some ')p.add_run('bold').bold = Truep...._python-doc table 右对齐

spark源码分析之任务本地化_任务本地化源码-程序员宅基地

文章浏览阅读235次。Spark也有数据本地化的概念(Data Locality),这和MapReduce的Local Task差不多,如果读取HDFS文件,Spark则会根据数据的存储位置,分配离数据存储最近的Executor去执行任务。这么理解没错,我搭建的Spark集群情况是这样:每台DataNode节点的HDFS集群,我在每个DataNode上都部署了一个Spark Worker,并且,启动Spark Ap..._任务本地化源码

世界最顶级邮件服务器组合Linux + PMTA + OEMPRO,PowerMTA 安装-程序员宅基地

文章浏览阅读2.6k次。世界最顶级邮件服务器组合Linux + PMTA + OEMPRO PowerMTA 安装PMTA + OEMPRO 这个是发送的组合 PMTA提供的SMTP,OEMPRO是订阅管理以及邮件的过滤等SPF, DKIM, Sender-ID, DNS, rDNS 这些各自有分工, 分别在DNS解析和联系主机商进行解析。pmta+iem是世界顶级的邮件服务器,每天单台服务器可投递百万级邮件,..._powermta 收件箱在哪个文件夹

随便推点

vue中使用swiper,左右箭头点击没有效果的解决方法_vue cursor: pointer 不生效-程序员宅基地

文章浏览阅读5.2k次。swiper作为一个开源的前端组件,主要用来做各种页面切换轮播的效果。在做左右切换效果时,发现点击左右箭头没有效果,原来是需要在左右箭头的页面标签上添加点击事件才行,代码如下,亲测可用<swiper ref="mySwiper" :options="swiperOptions"> <swiper-slide><div style="background-color: #5cb85c;height: 100%"><img src=_vue cursor: pointer 不生效

Unity自动打包工具_unity混淆工具obfuscar-程序员宅基地

文章浏览阅读2.4w次,点赞10次,收藏25次。Unity一键打包工具,一键生成几十个平台/渠道的安装包。_unity混淆工具obfuscar

mdns-repeater Multicast DNS repeater-程序员宅基地

文章浏览阅读1.1k次。https://github.com/lucasec/mdns-repeater代码来自上面的链接,这个东西有什么用处了1:模仿程序,可以显示多播数据的转发2:对 mDNS的数据进行转发3: 多播数据是无法穿越路由NAT,如 openwrt中的WAN和LAN对于的网络接口4:mdns-repeater 使用直接 接网络接口名称mdns-repeatereth0 br-lan 就可以实现数据在接口之间的转发5:mDNS 的简介mDNS , multicast DN.....

Python中.npz文件的读取_查看npz结构-程序员宅基地

文章浏览阅读8.5w次,点赞68次,收藏147次。有时候从网上下载的数据集扩展名(后缀名)是npz,我们需要对数据进行加载(读取):例如:识别猫狗图片的二分类,下的数据集分别为cat.npz和dog.npzimport numpy as npcat_data = np.load(‘cat.npz’)dog_data = np.load(‘dog.npz’)因为以npz结尾的数据集是压缩文件,里面还有其他的文件使用:cat_data.f..._查看npz结构

《异常检测——从经典算法到深度学习》10 Bagel: 基于条件 VAE 的鲁棒无监督KPI异常检测_robust and unsupervised kpi anomaly detection base-程序员宅基地

文章浏览阅读7.2k次,点赞26次,收藏18次。《异常检测——从经典算法到深度学习》0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: 基于 VAE 的 Web 应用周期性 KPI 无监督异常检测9 基于条件 VAE 的鲁棒无监督KPI异常检测2018 Robust and Unsupervised K_robust and unsupervised kpi anomaly detection based on conditional variation

solidworks工程图模板为什么不能存为slddrt格式-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏2次。不能直接存为SLDDRT,要先存为(*.DRWDOT),然后使用“文件”→“保存图纸格式”,保存为可以在工程图中可以查找到的模板文件。_slddrt

推荐文章

热门文章

相关标签