ES6 学习(三)-- es特性

文章目录

  • 1. Symbol
    • 1.1 使用Symbol 作为对象属性名
    • 1.2 使用Symbol 作为常量
  • 2. Iterator 迭代器
    • 2.1 for...of循环
    • 2.2 原生默认具备Interator 接口的对象
    • 2.3 给对象添加Iterator 迭代器
    • 2.4 ... 解构赋值
  • 3. Set 结构
    • 3.1 初识 Set
    • 3.2 Set 实例属性和方法
    • 3.3 遍历
    • 3.4 相关面试题
  • 4. Map 结构
    • 4.1 初识 Map
    • 4.2 Map 实例属性和方法
    • 4.3 遍历
  • 5. Proxy 代理
    • 5.1 Proxy 基本使用
    • 5.2 has()
    • 5.3 拦截set 结构

1. Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它属于JavaScript语言的原生数据类型之一,其他数据类型是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

1.1 使用Symbol 作为对象属性名

在开发过程中设置对象属性值时可能不小心就设置了本来就存在的属性,这样就会出现将原来的属性值直接覆盖的问题。
现在我们可以使用Symbol 数据类型来避免出现这种情况。

书写格式:
let s1 = Symbol()
// 生成了一个Symbol类型数据
[s1] = 赋值

这种构造函数创建出来的Symbol 类型数据是唯一的。

Lets1=Symbol()
Let s2 =Symbol()
console.log(s1===s2)

// false

Symbol 类型数据需要注意的是:

  1. 不能进行运算;
    console.log(s1>“aaaaa”)
  2. 显示调用toString()
    console.log(s1.tostring()+“aaaa”)
  3. 隐式转换Boolean
    if(s1){
    console.log(s1);
    }

Symbol 数据类型用初体验:

// 定义自己的公共库
let keys={
name:Symbol(),
age:Symbol(),
location:Symbol(),
test:Symbol()
}
// 对属性赋值
let obj ={
[keys.name]:"kerwin",
[keys.age]:100,
[keys.location]:"dalian",
[keys.test](){
console.log("test")

Symbol 对象也可以进行传参:
在这里插入图片描述

// Object{
name:“aaaaaaa”
Symbol(age):100
Symbol(location):“dalian”
Symbol(name):“kerwin”
Symbol(test):f keys.test
}

使用for…in… 循环只能遍历之前学习的五种基本数据类型,Symbol 类型的数据不能被遍历!
对此,解决办法是:
在这里插入图片描述
两种方法结合可以得到对象的所有类型数据

之后我们会学习Reflect 对象,使用

Reflect.ownKeys(obj).forEach(item=>{
console.log(item,obj[item])
)

就可以遍历对象的所有数据类型的属性

1.2 使用Symbol 作为常量

const VIDEO = Symbol();
const AUDIO = Symbol();
const IMAGE = Symbol();
function play(type){
switch(type){
case VIDEO:
console.log("视频播放")
break;
case AUDIO:
console.log("音频播放")
break;
case
IMAGE:
console.1og("图片播放")
break;
plav(AUDIO);

2. Iterator 迭代器

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

2.1 for…of循环

for…of循环使用:

Let arr ["aaaa","bbbb","cccc"]
for(let i of arr){
console.log(i)

// aaaa
// bbbb
// cccc

for…of循环能够使用的底层原理:
这些数据对象都存在一个Symbol(Symbol.iterator) 属性(接口)!

在这里插入图片描述

ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol…iterator)属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。
Iterator 遍历的底层逻辑:
在这里插入图片描述

我们定义一个两个对象:

// 定义自己的公共库
let keys={
name:Symbol(name),
age:Symbol(age),
location:Symbol(location),
test:Symbol(test)
}
// 对属性赋值
let obj ={
[keys.name]:"kerwin",
[keys.age]:100,
[keys.location]:"dalian",
[keys.test](){
console.log("test")

现在我们是不能通过obj[Symbol(age)]进行访问的,会报错;只能通过key.age找到。

2.2 原生默认具备Interator 接口的对象

在这里插入图片描述

arguments对象:
在这里插入图片描述

2.3 给对象添加Iterator 迭代器

对于大多数的对象是都不支持for…of 循环的,因为没有埋下Interator 接口,但是对象中的某个属性可能埋下了Interator 接口能够使用for…of 循环。

对象是无序列非线性的,但是我们自己学习数组的设计(使用Array.prototype[Symbol.Iterator]最为该对象的[Symbol.Iterator],同时添加属性数作为长度),这样可以为线性对象也就添加了Iterator接口。
在这里插入图片描述
// kerwin
// teichui
// ganger

但是我们一般也不会去创建例子中的数组,因为这种书组没有太大的实际意义;下面我们就学习对无序列非线性对象添加Iterator 迭代器!

let obj2={
code:200,
name: "obj2",
list: ["kerwin","tiechui","gangdan"],
// 这种对象我们也只能取到数组这种数据,取不到code 等这种数据,因为他们非线性,无规律
// list中信息是隐私的,我们使用迭代器是取不到的
// 迭代器
[Symbol.iterator](){
let index = 0
return
// next(){
// return
// {value:list[index++],done:false}
next:()=>{
//console.log(this)
return {value:this.list[index],
done:index===this.list.length?true:false}
}
for(Let i of obj2){
console.log(i)
}

2.4 … 解构赋值

在这里插入图片描述
… 结合解构赋值可以调用迭代器将非数组元素展开到数组中去,替代了Array,from()。

3. Set 结构

Set 结构类似于数组,但成员的值都是唯一的,没有重复的值。

3.1 初识 Set

  1. 创建Set 对象时传入参数;
let s1=new Set([1,2,3,2,3,4])
console.log(s1)
console.log([...s1])
// [1,2,3,4]
console.log(Array.from(s1))
// [1,2,3,4]
  1. 创建空的Set 对象
let s2 = new Set()
s2.add(1) // 向Set 结构中添加数据
s2.add(2)
s2.add(2)
s2.add(3)
console.log(s2)
for(let i of s1){
console.log(i)
}

3.2 Set 实例属性和方法

在这里插入图片描述

  1. x.size – 返回Set 结构的长度
    在这里插入图片描述
  2. x.add()
    在这里插入图片描述
  3. x.has()在这里插入图片描述
  4. x.delete()
    在这里插入图片描述
  5. x.clear()
    在这里插入图片描述

3.3 遍历

在这里插入图片描述

for(Let i of s2){
console.log(i)
}
for(Let i of s2.keys()){
console.log(i)
}
for(Let i of s2.values()){
console.log(i)
}
for(let i of s2.entries(){
console.log(i)
}

// 11
// 22
// 33
// 11
// 22
// 33
// 11
// 22
// 33
// (2) [11,11]
// (2) [22,22]
// (2) [33,33]

对于数组来说,普通for…of 只能拿到数值,而不能拿到索引

let arr = ["aa","bb","cc"]
for(let i of arr){
console.log(i)
}

// (2) [0,‘aa’]
// (2) [y,‘bb’]
// (2) [2,‘cc’]

所以我们可以使用解构赋值和arr.entries() 同时拿到数组的索引和数值。

Let arr ["aa","bb","cc"]
for(Let [index,item]of arr.entries()){
console.log(index,item)

// 0 ‘aa’
// 1 ‘bb’
// 2 ‘cc’

  1. foreach()
s2.forEach((item,index)=>{
console.log(item,index)
})
// foreach() 只能拿到数值,不能拿到索引

// 11 11
// 22 22
// 33 33

3.4 相关面试题

对字符串 / 对象 / 数组等复杂数据去重

let list = [1,2,2,"kerwin","kerwin",[1,2],[3,4],[1,2],{name:"kerwin"}
{age:100},{name:"kerwin"}]
function uni(arr){
Let res = new Set()
return arr.filter((item)=>{
//判断has trun false
//没有return true
Let id JSON.stringify(item)
if(res.has(id)){
return false
}else{
res.add(id)
return true}
})
}
console.log(uni(list))

4. Map 结构

类似于对象,也是键值对的集合,但是“键"的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

4.1 初识 Map

  1. 创建有参数的Map 结构
let m1 = new Map([
["name","kerwin"],
["age",100],
[{a:1},"大连"]])
console.log(m2)

在这里插入图片描述

  1. 创建空的Map 结构
let m2 = new Map()
m2.set("name","kerwin")// set() 添加数据
m2.set("age",100)
m2.set({a:1},"大连")
console.1og(m2)

在这里插入图片描述
证明Map 结构存在Iterator 迭代器

for(let i of m2){
console.log(i)
console.1og([...m2]

// (2)[‘name’,‘kerwin’]
// (2)[‘age’,100]
// (2)[{…},‘大连’]
// (3)[Array(2),Array(2),Array(2)]

4.2 Map 实例属性和方法

在这里插入图片描述

  1. Map.set()

  2. Map.get(key)
    如果key 为一个对象,比如{a: 1},那么就不能通过Map.get({a: 1}) 获取相应的值,只能通过设置let o = {a: 1};同时将o 作为key 把数据传入Map 结构中。(因为此时key 只是储存了数据地址,我们)
    在这里插入图片描述
    // 大连

  3. Map.has(key)
    在这里插入图片描述
    // true

  4. Map.size
    在这里插入图片描述

  5. Map.clear
    在这里插入图片描述

4.3 遍历

let m1 = new Map([
["name","kerwin"],
["age",100],
[{a:1},"大连"]])
for(let i of m1.values()){
console.log(i)}
for(let [index,item] of m1.entries()){
console.log(index,item)}
for(let [index,item] of m1){
console.log(index,item)}

// kerwin
// 100
// 大连
// name kerwin
// age 100
// {a:1} ‘大连’
// name kerwin
// age 100
// {a:1} ‘大连’

m1.entries() 和m1 的迭代器可能是同一个

5. Proxy 代理

Proxy如其名,它的作用是在对象和和对象的属性值之间设置一个代理,获取该对象的值或者设置该对象的值,以及实例化等等多种操作,都会被拦截住,经过这一层我们可以统一处理,我们可以认为它就是"代理器"

没有出现Proxy 代理的时候我们使用的是object.defineProperty(obj, 被修改拦截的属性, {get(){}, set(){}})。可以修改操作DOM元素。

<div id="box"></div>
<script>
Let obj = {
// console.log(box) 实际上我们可以直接通过id 直接访问到DOM 元素
// 拦截操作
object.defineProperty(obj,"data",
get(){
console.log("get")
return box.innerHTML
}
set(value){
console.log("set",value)
//设置dom
box.innerHTML = vaLue
})
console.log(obj)
</script>

但是这种方法存在漏洞:

  1. 只能拦截修改一个属性,如果想要拦截修改对象的全部属性只能通过遍历实现;
  2. 只能拦截对象

5.1 Proxy 基本使用

get() 和set() 的使用:

<div id="box"></div>
<script>
let obj = {}
let proxy = new Proxy(obj,
get(target,key){
console.log("get",target[key])
return target[key]}
// 其中target 就是指obj 
set(target,key,value){
console.log("set",target,key,value)
if(key==="data"){
box.innerHTML = value
target[key] = vaLue}
})
</script>

此时就不能再通过obj 进行访问相应属性,只能通过proxy 进行访问

5.2 has()

has() – 判断Proxy 代理对象是否含有某个属性
在这里插入图片描述
如果has() 中return 的是false ,那么访问proxy 的任何属性,has()结果都是false

has() 使用较少,仅仅知道就可以了

5.3 拦截set 结构

在这里插入图片描述
在这里插入图片描述
按照以下方式修改:
在这里插入图片描述

拦截set 结构时最容易出现的问题:
在这里插入图片描述
add() 中有this 指向,

Let s new Set()
Let proxy new Proxy(s,
get(target,key){
//判断如果key 是方法,修正this指向
Let value = target[key]
if(value instanceof Function){
//call apply bind
return value.bind(target)}
return value
},
set(){
console.log("set")
})

Proxy本质上属于元编程非破坏性数据劫持,在原对象的基础上进行了功能的衍生而又不影响原对象,符合松耦合高内聚的设计理念。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/778200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

a = 3中的3在栈中还是堆中?

1、栈区&#xff08;stack&#xff09; 由编译器自动分配释放&#xff0c;存放函数的参数值&#xff0c;局部变量的值等。 2、堆区&#xff08;heap&#xff09; 是一个可动态申请的内存空间&#xff08;其记录空闲内存空间的链表由操作系统维护&#xff09;&#xff0c;在j…

基于js css的瀑布流demo

要实现照片按照瀑布流展示&#xff0c;写个小demo&#xff0c;记录下。 瀑布流实现思路如下&#xff1a; CSS 弹性布局对 3 列按横向排列&#xff0c;对每一列内部按纵向排列 html代码&#xff1a; <div class"content"></div> css代码&#xff1a; …

基于SSM学生信息管理系统

采用技术 基于SSM学生信息管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringMVCMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 总体功能设计 登录页面 后台首页 学生信息页面 添加学生用户 编辑…

动态规划刷题(算法竞赛、蓝桥杯)--导弹拦截(线性DP)

1、题目链接&#xff1a;[NOIP1999 提高组] 导弹拦截 - 洛谷 #include <bits/stdc.h> using namespace std; const int N2e55; int a[N],x,n; int b[N],len;int main(){while(cin>>x)a[n]x;//求最长不上升子序列 b[0]2e9;//初始化为无穷大for(int i1;i<n;i){if(…

计算机专业在找工作时的注意事项

目录 说在前面关于我一些忠告关于简历关于银行写在最后 说在前面 满满的求生欲。我不是什么大佬&#xff0c;更没有能力教大家什么。只是看到有不少学弟学妹&#xff0c;还在为找一份工作焦头烂额&#xff0c;却没有努力的方向。所以这里斗胆给计算机相关专业的学弟学妹们的一…

进程知识点

引用的文章&#xff1a;操作系统——进程通信&#xff08;IPC&#xff09;_系统ipc-CSDN博客 面试汇总(五)&#xff1a;操作系统常见面试总结(一)&#xff1a;进程与线程的相关知识点 - 知乎 (zhihu.com) 二、进程的定义、组成、组成方式及特征_进程的组成部分必须包含-CSDN博…

江协科技STM32:按键控制LED光敏传感器控制蜂鸣器

按键控制LED LED模块 左上角PA0用上拉输入模式&#xff0c;如果此时引脚悬空&#xff0c;PA0就是高电平&#xff0c;这种方式下&#xff0c;按下按键&#xff0c;引脚为低电平&#xff0c;松下按键&#xff0c;引脚为高电平 右上角PA0&#xff0c;把上拉电阻想象成弹簧 当按键…

c++中的菱形继承

c中的菱形继承 class Animal { public:int m_age; }; class Sheep:public Animal {}; class Tuo:public Animal{}; class SheepTuo :public Sheep , public Tuo{}; SheepTuo st; st.m_age 18; m_age是谁的无法区分 class Animal { public:int m_age; }; class Sheep:virtua…

李宏毅【生成式AI导论 2024】第5讲 让语言模型彼此合作,把一个人活成一个团队

GPD4,它也有非常强大的能力。但是GPT4如果跟其他的语言模型合作,他们其实可以发挥1加1大于二的力量。 为什么要让模型合作? 那怎么让模型彼此合作呢?有很多不同的方式。一个可能性是假设你现在手边就有一堆语言模型,他们可能有不同的能力使用,他们可能有不同的成本局来…

国外的Java面试题和国内的相比谁更卷

前言 有很多朋友很好奇国外的Java面试题长啥样&#xff0c;今天我们就去找5道国外的面试来和国内的对比一下看看谁难一些&#xff01; 面试题分享 1. Is Java Platform Independent if then how?&#xff08; Java平台是独立的吗&#xff1f;&#xff09; Yes, Java is a…

[数据结构]插入和希尔排序

一、插入排序 插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴&#xff0c;但它的原理应该是最容易理解的了&#xff0c;因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法&#xff0c;它的工作原理是通过构建有序序列&#xff0c;对于未排…

win10微软拼音输入法 - bug - 在PATH变量为空的情况下,无法输入中文

文章目录 win10微软拼音输入法 - bug - 在PATH变量为空的情况下&#xff0c;无法输入中文概述笔记实验前提条件100%可以重现 - 无法使用win10拼音输入法输入中文替代的输入法软件备注END win10微软拼音输入法 - bug - 在PATH变量为空的情况下&#xff0c;无法输入中文 概述 在…

Day54:WEB攻防-XSS跨站Cookie盗取表单劫持网络钓鱼溯源分析项目平台框架

目录 XSS跨站-攻击利用-凭据盗取 XSS跨站-攻击利用-数据提交 XSS跨站-攻击利用-flash钓鱼 XSS跨站-攻击利用-溯源综合 知识点&#xff1a; 1、XSS跨站-攻击利用-凭据盗取 2、XSS跨站-攻击利用-数据提交 3、XSS跨站-攻击利用-网络钓鱼 4、XSS跨站-攻击利用-溯源综合 漏洞原理…

计算机网络链路层

数据链路 链路是从一个节点到相邻节点之间的物理线路&#xff08;有线或无线&#xff09; 数据链路是指把实现协议的软件和硬件加到对应链路上。帧是点对点信道的数据链路层的协议数据单元。 点对点信道 通信的主要步骤&#xff1a; 节点a的数据链路层将网络层交下来的包添…

深度学习pytorch——卷积神经网络(持续更新)

计算机如何解析图片&#xff1f; 在计算机的眼中&#xff0c;一张灰度图片&#xff0c;就是许多个数字组成的二维矩阵&#xff0c;每个数字就是此点的像素值&#xff08;图-1&#xff09;。在存储时&#xff0c;像素值通常位于[0, 255]区间&#xff0c;在深度学习中&#xff0…

重写、重定义(隐藏)、重载区别

1、重载是在同一个作用域中比如在同一个类中、函数名一样参数不同 2、重写&#xff1a; 满足多态的条件&#xff1a;&#xff08;1&#xff09;虚函数前面带有virtual函数名、返回值、参数相同&#xff08;2&#xff09;重写函数体 3、重定义也叫隐藏、不满足重写的就是重定义

SlerfTools:简化操作,激发Solana生态创新潜能

在区块链世界的快速演变中,Solana生态系统以其独特的高性能吸引了全球的目光。然而,随着生态系统的蓬勃发展,用户和开发者面临的挑战也日渐增多。正是在这样的背景下,一个名为SlerfTools的新星项目应运而生,它承诺将为Solana带来一场革命性的变革。 项目的诞生 SlerfTools并非…

前端学习-CSS基础-Day3

一、CSS三大特性 1.1层叠性 相同选择器给设置相同的样式&#xff0c;此时一个样式就会覆盖&#xff08;层叠&#xff09;另一个冲突的样式。层叠性主要解决样式冲突的问题 层叠性原则&#xff1a; 1.样式冲突&#xff0c;遵循的原则是就近原则&#xff0c;哪个样式离结构近&a…

【QT+QGIS跨平台编译】043:【libprotobuf-lite+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、libprotobuf-lite介绍二、文件下载三、文件分析四、pro文件五、编译实践一、libprotobuf-lite介绍 libprotobuf-lite 是 Protocol Buffers 的 C++ 轻量级运行时库,专门设计用于在资源受限的环境下使用。与标准的 libprotobuf(Protocol Buffers…

数据结构——AVL树详解

一、AVL树的定义 AVL全称叫做平衡二叉搜索&#xff08;搜索&#xff09;树&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.Landis在1962年发明了一种方法&#xff1a; 当向二叉搜索树中插入新结点后&#xff0c;如果能保证每个结点的左右子树高度之差的绝对值不超…