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

目录

一、对象扩展

二、函数的扩展

三、Symbol

四、Iterator 迭代器

五、Set结构

六、Map 数据结构

一、对象扩展

1. 对象简写

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

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

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

2. 对象属性 表达式

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

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

3. 扩展运算符

    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 视为相等

    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,表示独一无二的值(不能进行运算)

    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( )获得所有的属性名(返回一个数组)

    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. 作为常量

    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 循环 

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

     Array

     Set

     Map

     String

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

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

工作原理:

  1. 创建一个指针对象,指向该数据结构的起始位置

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

  3. 接下来不断调用 next 方法,指针一直向后移动,直到指向最后一个成员

  4. 每次调用 next 方法,返回一个包含 value 和 done 属性的对象

注:需要自定义遍历数据的时候,要想到迭代器。 

Symbol.iterator 是一个内置值

自定义的迭代器:

        const banji = {
            name: '终极一班',
            stus: [
                '小明',
                'xiaoning',
                'xiaotian',
                'knight'
            ],

            [Symbol.iterator](){
                let index = 0
                
                return {
                    next: () => {
                        if (index < this.stus.length) {
                            return { value: this.stus[index++], done: false }
                        } else {
                            return {value: undefined, done: true}
                        }
                    }
                }
            }
    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());

  

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

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

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

    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( )对数组去重

    // 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 等

数组:

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

字符串:

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

arguments:

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:

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 指向。

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 
*/
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

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

【什么时候使用 Set】

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

 5. Set的应用

数组去重

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

字符串去重

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

复杂数据类型去重

    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元素

<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 了。

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)

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 等

 【二维数组】

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

 【Set、Map】

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对象,因此可以采用链式写法。

const m = new Map();

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

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

  const m = new Map();

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

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

  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( ) 方法 

  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】

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值