对象扩展、函数的扩展、Symbol、Iterator 迭代器、Set结构、Map 数据结构——ES6+

news/2024/7/10 23:59:59 标签: 前端, javascript, es6

目录

一、对象扩展

二、函数的扩展

三、Symbol

四、Iterator 迭代器

五、Set结构

六、Map 数据结构

一、对象扩展

1. 对象简写

对于对象属性,属性名与属性值对应的变量相同时,可简写为属性名

对于对象方法,将 :function 去掉

javascript">    let name = 'pink'
    const obj = {
      name,   //是 name: name的简写属性名与属性值的变量相同,
      test1(){  //是 test1: function(){ }的简写
        console.log('test1')
      },
      test2(){
        console.log('test2')
      }
    }

2. 对象属性 表达式

使用 [ ] 操作属性时,可以使用变量

javascript">    let name = 'pink'
    const obj = {
      name,   //是 name: name的简写属性名与属性值的变量相同,
      [name + 'test1'](){ //属性表达式,表示为 pinktest1
        console.log(1);
      }
    }

3. 扩展运算符

javascript">    const obj = {
      name: 'pink'
    }
    const obj1 = {
      ...obj
    }
    console.log(obj1) //{name: 'pink'}
    const obj2 = {
      age: 100
    }
    const obj3 = {...obj1, ...obj2}
    console.log(obj3) //{name: 'pink', age: 100}

4. Object.assign( )、Object.is( )

Object.assign( )

     语法: 

Object.assign(target, ...sources)

   target 目标对象,接收源对象属性的对象,也是修改后的返回值。

   sources  源对象,包含将被合并的属性。

会直接将目标对象修改,破坏性方法

Object.is( ) 判断两个值是否为同一个值

  Object.is( ) 与 == 不相同 ,==会进行类型转换 ,而Object.is( )不会进行类型转换。

  Object.is( ) 与 === 不相同,差别是对待有符号的零和 NaN不同,===运算符将数字 +0 与 -0判断为true, 对于两个 NaN判断为 false; Object.is( )将两个 NaN 视为相等

javascript">    console.log(Object.is(5, '5')) //false
    console.log(Object.is(parseInt('pink'), NaN)) //true
    console.log(parseInt('pink') === NaN) //false

二、函数的扩展

1. 参数默认值

2. 剩余参数

得到的是真数组

3. name属性

4. 箭头函数 ,使得写法更简洁

只有return 可省略

如果返回对象需注意加上小括号

如果只有一个参数,可以省略 ( )

箭头函数中没有 arguments ,无法 new(作为构造函数)

箭头函数没有 this,  this 指向父作用域

三、Symbol

ES6引入了一种新的原始数据类型 symbol,表示独一无二的值(不能进行运算)

javascript">    let s1 = Symbol() //生成了一个 Symbol类型的数据
    let s2 = Symbol() //生成了一个 Symbol类型的数据
    console.log(typeof s1) //symbol
    console.log(s1 == s2) //false

1. 使用 Symbol 作为对象属性名,保护对象的属性,避免冲突的机制

传参,对 symbol 的描述,可用于调试但不是访问 symbol 本身

注意: for in 只能遍历出普通属性和方法,对于使用 Symbol建立的属性及方法无法遍历

可使用Object.getOwnPropertySymbols( ) 获得 symbol属性名

Reflect.ownKeys( )获得所有的属性名(返回一个数组)

javascript">    let name = Symbol("name")
    let age = Symbol("age")
    const obj = {
      [name]: 'pink',
      [age]: 18,
      name: 'tiechui',
      getName(){
        console.log(this.name);
      }
    }
    console.log(obj[name]);
    console.log(obj);
    obj.getName()
    console.log(Object.getOwnPropertySymbols(obj));
    console.log(Reflect.ownKeys(obj));
    Reflect.ownKeys(obj).forEach(item => {
      console.log(item, obj[item]);
    })

2. Symbol( ) 函数可以接收一个字符串作为参数,表示对 Symbol 实例的描述

3. 作为常量

javascript">    function play(type) {
      // 该函数想播放视频、音频
      switch(type) {
        case VIDEO:
          console.log('视频播放');
          break
        case AUDIO:
          console.log('音频播放');
          break
        case IMAGE:
          console.log('图片播放');
          break
      }
    }
    const VIDEO = Symbol()
    const AUDIO = Symbol()
    const IMAGE = Symbol()
    play(VIDEO)

四、Iterator 迭代器

Iterator 的作用有三个:

      1. 是为各种数据结构,提供一个统一的,简便的访问接口;

      2. 使得数据结构的成员能够按某种次序排列

      3. ES6 创造了一种新的遍历命令 for ... of 循环,iterator 接口主要供 for ... of 循环 

Symbol.iterator 是一个内置值

javascript">    const obj = {
      name: 'hh',
      age: 18,
      [Symbol.iterator](){
        console.log('iterator');
      }
    }
    console.log(obj);

    const arr = ['red', 'pink', 'blue']
    let iter = arr[Symbol.iterator]()
    // 返回的就是遍历器对象
    console.log(iter); 
    console.log(iter.next());
    console.log(iter.next());
    console.log(iter.next());
    console.log(iter.next());

  

 原生默认具备 iterator 接口的数据结构如下:

     Array

     Set

     Map

     String

     Arguments 对象,函数中的内置对象(伪数组)

     NodeList 对象, 获取的DOM节点(伪数组)

如何对对象进行 for of 遍历?(对象不能迭代是因为对象是非线性的,无序的)

javascript">    const obj = {
      0: 'red',
      1: 'blue',
      2: 'pink',
      length: 3,
      [Symbol.iterator]: Array.prototype[Symbol.iterator]
    }

如果对象中有某个属性是数组,但是该对象是传过来的黑盒子,不知道该属性名称,之前对该对象添加迭代器是非常有必要的,以至于让该对象通过 for  of进行遍历该属性的数组

javascript">    const obj2 = {
      code: 200,
      name: 'hh',
      list: ['a', 'b','c'],
      // 迭代器
      [Symbol.iterator](){
        let index = 0
        return {
          next:() => {
            return {
              value:this.list[index++], 
              done: index >=(this.list.length + 1) ? true : false}
          }
        }
      }
    }
    let iter = obj2[Symbol.iterator]()
    // console.log(iter);
    // console.log(iter.next());
    // console.log(iter.next());
    for(let i of obj2) {
      console.log(i);
    }

五、Set结构

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

        Set 是一系列无序、没有重复值的数据集合。数组是一系列有序(下标索引)的数据集合。

可以通过Set( ),与展开运算符对数组进行去重,[...new Set(数组)]

1.初识Set,两种初始化的方法,使用Set( )对数组去重

javascript">    // Set初始化第一种方式
    const s1 = new Set([1,2,3,2,4])
    console.log(s1);  //Set(4) {1, 2, 3, 4}
    console.log([...s1]);  // [1, 2, 3, 4]
    console.log(Array.from(s1));  // [1, 2, 3, 4]
    //Set初始化第二种方式
    let s2 = new Set()
    s2.add(1)
    s2.add(2)
    s2.add(2)
    s2.add(4)
    console.log((s2)); //Set(3) {1, 2, 4}

    for(let i of s1) {
      console.log(i);
    }

2.  Set 构造函数的参数

数组、字符串、arguments、NodeList、Set 等

数组:

javascript">const s = new Set([1, 2, 1]);
console.log(s);		// Set(2) { 1, 2 }

字符串:

javascript">    const s = new Set('hello')
    console.log(s); //Set(4) {'h', 'e', 'l', 'o'}

arguments:

javascript">function func() {
    console.log(new Set(arguments));
}
func(1, 2, 1);	// Set(2) { 1, 2 }

NodeList:

<p>1</p>
<p>2</p>
<p>3</p>
<script>
    console.log(new Set(document.querySelectorAll('P')));//Set(3) {p, p, p}
</script>

 Set:

javascript">const s = new Set([1, 2, 1]);
console.log(new Set(s));	// Set(2) { 1, 2 }
console.log(s);				// Set(2) { 1, 2 }
// 这也是复制一个 Set 的方法

3. Set 实例属性和方法

实例属性 size 返回Set 对象中值的个数

实例方法

    add(value)   Set对象中没有具有相同值的元素,则将插入一个具有指定值的新元素到Set对象中

    has( value)方法返回一个布尔值来指示对应的值是否存在于Set对象中

    delete( value)   从对象中删除指定的值(该值存在于Set对象中),成功删除返回true,否则返回 false

    clear( )   移除Set对象中所有元素,没有返回值 undefined

    forEach( )  用于遍历 Set 的(按照成员添加进集合的顺序遍历)

       forEach 方法可以接受两个参数,第一个是:回调函数,第二个是指定回调函数的 this 指向。

javascript">const s = new Set();
s.add(0);
s.add(1).add(2).add(2).add(3);

s.forEach(function (value, key, set) {
    // Set 中 value = key,原因:好多数据结构都有 forEach 方法,为了方便统一,所以参数是统一的,但是参数的意义各有不同
    // set 就是 s 本身
    console.log(value, key, set === s);
    console.log(this);
});

/*
0 0 true
Window
1 1 true
Window
2 2 true
Window
3 3 true
Window 
*/
javascript">const s = new Set();
s.add(0);
s.add(1).add(2).add(2).add(3);

s.forEach(function (value, key, set) {
    // Set 中 value = key,原因:好多数据结构都有 forEach 方法,为了方便统一,所以参数是统一的,但是参数的意义各有不同
    // set 就是 s 本身
    console.log(value, key, set === s);
    console.log(this);
}, document);

/*
0 0 true
#document
1 1 true
#document
2 2 true
#document
3 3 true
#document
*/

4. Set 注意事项

【Set 如何判断重复】

       Set 对重复值的判断基本遵循严格相等(===)

       但是对于 NaN 的判断与 === 不同,Set 中 NaN 等于 NaN

javascript">const s = new Set();
s.add({}).add({});
console.log({} === {});	 // false
console.log(s);			 // Set(2) { {}, {} }

【什么时候使用 Set】

  • 数组或字符串需要去重
  • 不需要通过下标访问,只需要遍历时
  • 为了使用 Set 提供的方法和属性时

 5. Set的应用

数组去重

javascript">const s = new Set([1, 2, 1]);
console.log(s);			// Set(2) { 1, 2 }
console.log([...s]);	// [ 1, 2 ]

字符串去重

javascript">const s = new Set('abbacbd');
console.log(s);					// Set(4) { 'a', 'b', 'c', 'd' }
console.log([...s].join(''));	// abcd

复杂数据类型去重

javascript">    let list = [1,2,2,'ke','ke',[1,2],[3,4],[1,2],{name:'ke'},
    {name:'ke'},undefined,undefined,NaN,NaN]
    function uni(arr) {
      let res = new Set()
      return arr.filter(item => {
        // 判断 已经存在 ,return false
        // 判断 没有,return true
        let id = JSON.stringify(item)      
        // console.log(id);
        if(res.has(id)) {
          return false
        } else {
          res.add(id)
          return true
        } 
      })
    }
    
    console.log(uni(list));

存放DOM元素

javascript"><p>1</p>
<p>2</p>
<p>3</p>
<script>
    // 这里使用 Set 是因为我们不需要通过下标去访问,只需直接遍历即可
    const s = new Set(document.querySelectorAll('p'));
    s.forEach(function (elem) {
        elem.style.color = 'red';
    });
</script>

遍历 

 数组的mapfilter方法也可以间接用于 Set 了。

javascript">let set = new Set([1, 2, 3]);
set = new Set([...set].map(x => x * 2));
// 返回Set结构:{2, 4, 6}

let set = new Set([1, 2, 3, 4, 5]);
set = new Set([...set].filter(x => (x % 2) == 0));
// 返回Set结构:{2, 4}

 因此使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)

javascript">let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

六、Map 数据结构

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

1. Map 构造函数中的参数

  • 二维数组
  • Set、Map 等

 【二维数组】

javascript">console.log(new Map([
    ['name', 'alex'],
    ['age', 18]
]));
// Map(2) { 'name' => 'alex', 'age' => 18 }

 【Set、Map】

javascript">console.log(new Map([
    ['name', 'alex'],
    ['age', 18]
]));
// Map(2) { 'name' => 'alex', 'age' => 18 }
【Set、Map】


// Set
// Set 中也必须体现出键和值
const s = new Set([
    ['name', 'alex'],
    ['age', 18]
]);
console.log(new Map(s));
console.log(s);
// Map(2) { 'name' => 'alex', 'age' => 18 }
// Set(2) { [ 'name', 'alex' ], [ 'age', 18 ] }

// Map
const m = new Map([
    ['name', 'alex'],
    ['age', 18]
]);
console.log(m);
const m2 = new Map(m);
console.log(m2, m2 === m);
// Map(2) { 'name' => 'alex', 'age' => 18 }
// Map(2) { 'name' => 'alex', 'age' => 18 } false
// Map 复制的方法

2. Map 实例方法和属性

    set( ) 方法  设置键名key 对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。方法返回的是当前的Map对象,因此可以采用链式写法。

javascript">const m = new Map();

m.set('edition', 6)        // 键是字符串
m.set(262, 'standard')     // 键是数值
m.set(undefined, 'nah')    // 键是 undefined

     get( ) 方法  读取key对应的键值,如果找不到key,返回undefined。

javascript">  const m = new Map();

  const hello = function() {console.log('hello')}
  m.set(hello, 'Hello ES6!') // 键是函数
  m.get(hello)  // Hello ES6!

      has( ) 方法 返回一个布尔值,表示某个 键是否在当前 Map对象中

javascript">  const m = new Map();

  m.set('edition', 6);
  m.set(262, 'standard');
  m.set(undefined, 'nah');

  console.log(m.has('edition') );   // true
  console.log(m.has('years') );   // true
  console.log(m.has(262) );   //false

      delete( ) 方法 删除某个键,返回 true。如果删除失败,返回 false

      clear( ) 方法 清除所有成员,没有返回值

      forEach( ) 方法 

javascript">  const m = new Map([['name','hh'],[undefined,1]]);

  m.forEach(function (value, key, map) {
    console.log(value,key,map);
    console.log(this);
  }, document);

      size 属性 

3. Map 注意事项

【Map 如何判断键名是否相同】

在 Set 中遇到重复的值直接去掉后者,而 Map 中遇到重复的键值则是后面的覆盖前面的。

  • 基本遵循严格相等(===)
  • Map 中 NaN 也是等于 NaN

【什么时候使用 Map】

  • 如果只是需要键值对结构
  • 需要字符串以外的值做键
  • 对象一般用在模拟实体上

 


http://www.niftyadmin.cn/n/108405.html

相关文章

北极星指标体系

北极星指标体系 每个产品都有很多指标,每个指标都反映了对应业务的经营情况。但是在实际业务经营中,却要求我们在不同的产品阶段寻找到合适的指标,让这个指标可以代表当前产品阶段的方向和目标,让这个指标不仅对业务经营团队,而且对产品的用户、对产品的价值都能有很好的…

Samba文件共享服务器的配置

一、Samba服务&#xff1a; 1&#xff09;SMB&#xff08;Server Message Block&#xff09;协议实现文件共享&#xff0c;也称为CIFS&#xff08;Common Internet File System&#xff09; 2&#xff09;是Windows和类Unix系统之间的共享文件的一种协议。NFS是Linux和Linux之…

Zynq UltraScale系列使用MIPI CSI-2 RX Subsystem 解码MIPI视频PD输出 提供2套工程源码和技术支持

目录1、前言2、设计思路和架构3、vivado工程详解4、上板调试验证5、福利&#xff1a;工程代码的获取1、前言 本设计采用OV5640摄像头MIPI模式作为输入&#xff0c;分辨率为1280x72060Hz&#xff0c;MIPI解码方案采用Xilinx官方提供的MIPI CSI-2 RX Subsystem IP解码MIPI视频&a…

【RocketMQ】RocketMQ 5.0版本任意时刻延迟消息的实现原理浅析

文章目录意外发现设计方案时间轮定时消息存储具体实现流程图流程步骤意外发现 无意间从官方的最新的客户端代码中看到下面的Example&#xff1a; 感兴趣的可以看看这个介绍&#xff1a;https://rocketmq.apache.org/docs/featureBehavior/02delaymessage 生产者&#xff1a;…

创建自助服务知识库的指南

在SaaS领域&#xff0c;自助文档是你可以在客户登录你的网站时为他们提供的最灵活的帮助方式&#xff0c;简单来说&#xff0c;一个自助知识库是一个可以帮助许多客户的文档&#xff0c;拥有出色的自助服务知识库&#xff0c;放在官网或者醒目的地方&#xff0c;借助自助服务知…

C语言易错小贴士

1.数组建立以及strlen&#xff1a; char arr1[]"bit"; char arr2[]{b,i,t}; char arr3[]{b,i,t,\0}; 1&#xff09;其中arr1数组需要注意默认为4个字符&#xff0c;和arr3包含的内容是一致的&#xff1b; 2&#xff09;arr2末尾没有\0&#xff0c;后面是数组越界的…

【ROS学习笔记7】ROS中的常用命令行

【ROS学习笔记7】ROS中的常用命令行 文章目录【ROS学习笔记7】ROS中的常用命令行前言一、rosnode二、rostopic三、rosmsg四、rosservice五、rossrv六、rosparam七、Reference写在前面&#xff0c;本系列笔记参考的是AutoLabor的教程&#xff0c;具体项目地址在 这里 前言 机器…

《C++ Primer》第七章 类

《C Primer》第七章 类 7.1 定义抽象数据类型 类的基本思想是数据抽象与封装。数据抽象是一种以利于接口和实现分离的变成技术。要想实现数据抽象与封装&#xff0c;需要先定义一个抽象数据类型。 类内&#xff1a; this: 总是指向"这个"对象&#xff0c;是一个常…