68-解构赋值,迭代器,生成器函数,Symbol

1.解构赋值(针对数组array,字符串String及对象object以)

结构赋值是一种特殊的语法,通过将各种结构中的元素复制到变量中达到"解构"的目的,但是数组本身没有改变

1.1解构单层数组

    <script>
      let arr = [1,2,3,4,5];
      //获取数组中的第一个元素
      let ha = arr[0];
      //获取数组中的每一个元素
      //将数组arr中的元素一次赋值给变量a,b,c,d,e
      let [a,b,c,d,e] = arr;
      console.log(a,b,c,d,e);//输出1 2 3 4 5
      //取第3个值,数组中不想要的元素可以添加逗号把它丢弃
      let [a1,,c1] = arr;//等于let [,,c1] = arr;
      console.log(c1);//输出3
    </script>

1.2解构多层次的数组

    <script>
      let array = [[1,2,3],[4,5,6],[7,8,9]];
      //解构获取数组第3个元素的第2个元素
      let [,,[,b]] = array;
      console.log(b);//输出8
    </script>

1.3解构字符串类型String同上

    <script>
      let string = 'xyz';
      let [a,b,c] = string;
      console.log(a,b,c);//输出x y z
      [,,c] = string;
      console.log(c);//输出z
    </script>

1.4解构赋值对象Object

按对象中的属性名进行解构赋值,修改变量名

    <script>
      let obj = {
        name:'张三',
        age:18,
      };
      //按属性名进行解构
      let {name,age} = obj;
      console.log(name);//输出张三
      //修改变量名
      let {name:aaa,age:bbb} = obj;
      console.log(bbb);//输出18//aaa,bbb是重新声明的变量名称
    </script>

对已经存在的变量进行解构赋值

    <script>
      let obj = {
        name:'张三',
        age:18,
      };
      let name,age;
      //{name,age} = obj;//报错,语句被解析为对代码块进行赋值,代码块不允许被赋值
      ({name,age} = obj);//解决办法加一个()
      console.log(name,age);//输出 张三 18
    </script>

默认值属性值为undefined时默认值生效

    <script>
      let obj = {
        name:'张三',
        age:18,
      };
      let {name,age,_sex:sex='男'} = obj;
      console.log(name,age,sex);//输出 张三 18 男
      let abc = {
        name1:'李四',
        age1:'19',
        _sex1:'女',
      }
      let {name1,age1,_sex1:sex2='男'} = abc
      console.log(name1,age1,sex2);//输出 李四 19 女//默认值被覆盖
    </script>

嵌套解构赋值

    <script>
      let obj = {
        name:'张三',
        age:18,
        hobby:['足球'],//hobby是数组用[],作用是定位
      };
      let {name,hobby:[a]} = obj;
      console.log(name,a);//输出张三 足球
    </script>

2.迭代器

迭代器对象是由 可迭代协议([Symbol.iterator]方法) 和 迭代器协议(next方法) 构成

迭代器是一个对象,定义一个序列,并在终止时可能附带一个返回值;

2.1枚举for-in,会无序遍历对象里面的属性(没有办法自定义循环过程)

  <body>
    <script>
      let obj = {
        name:'zhangsan',
        age:19,
      };
      for(let index in obj){//index代表索引和属性
        console.log(index,obj[index]);
        //index代表所有属性名,obj[index]代表所有属性值
      }
    </script>

2.2可迭代协议

有一个[Symbol.iterator]方法,需要返回一个迭代器对象,具有唯一性

2.3迭代器协议

迭代器通过使用 next() 方法实现了迭代器协议的任何一个对象,该方法返回具有两个属性对象

value:迭代的值;

done:是否迭代完完成;(ture迭代完成)(false迭代完成)

2.4迭代for-of,自定义遍历过程 

    <script>
      let obj = {
        //obj是一个迭代器对象,因为里面拥有一个next方法并且返回了一个值
        name: "zhangsan",
        age: 19,
        count: 5,
        //可迭代协议 条件1
        [Symbol.iterator]: function () {  
          return this;//返回迭代器对象 条件2
        },
        //迭代器协议 条件1
        next() {
          if (this.count > 0) {
            return { value: this.count--, done: false };//迭代器协议 条件2
          }else{
            return{value:0,done:true};
          }
        },
      };
      //迭代
      for (let item of obj) {
        console.log(item);//输出5 4 3 2 1//item拿到的是if里面value的值
      }
    </script>

3.生成器函数

生成器对象(generator)是由一个generator function返回的,它同时符合可迭代协议和迭代器协议

 生成器函数是一种特殊类型的函数,它返回一个生成器对象,这个对象可以用来实现可迭代对象。它可以使用特殊的语法来控制生成器对象的输出,实现按需生成值序列,避免一次性生成大量的值,减少了内存的使用(都是为了构建可迭代对象,自定义迭代过程)

3.1生成器函数定义使用function*关键字,语法如下:

function* generator() {
  // 函数体
}
    <script>
      function*  generator(){
        console.log('run1');
        //return默认返回undefined
      }
      //调用生成器函数,返回生成器对象,--此时生成器函数的代码块并不执行
      
      let g = generator();//g是一个生成器对象
      console.log(g);
      
      g.next();//调用生成器函数当中的next()方法//此时生成器函数当中的代码块开始执行
      let r = g.next();
      console.log(r);//输出结果如下
    </script>

 3.2yield关键字,暂停代码执行,并将后面的值返回

function* generateSequence() {
  yield 1;
  yield 2;
  yield 3;
}

const generator = generateSequence();

console.log(generator.next().value); // 1
console.log(generator.next().value); // 2
console.log(generator.next().value); // 3

3.3结束迭代.return()

    <script>
      function*  generator(){
        yield 1;
        yield 2;
        yield 3;
      }
      let g = generator();
      let r1 = g.next();
      g.return();
      let r2 = g.next();
      let r3 = g.next();
      console.log(r1,r2,r3);//{value: 1, done: false}
                            //{value: undefined, done: true}
                            //{value: undefined, done: true}
    </script>

3.4生成器函数的应用

yield*(展开可得迭代对象)

    <script>
      let obj = {
        name:'张三',
        age:18,
        sex:'男',
        *[Symbol.iterator](){
          yield [this.name,this.age,this.sex];//['张三', 18, '男']
          //yield this.name;
          //yield this.age;
          //yield this.sex;简约写法
          yield* [this.name,this.age,this.sex];
        },
      };
      //迭代对象
      for(const item of obj){
        console.log(item);
      }
    </script>

 内嵌式对象应用

    <script>
      let obj = {
        hobbies:['篮球','足球','品胖球'],
        *[Symbol.iterator](){
          //Object.values()是Object对象中的静态方法
          //返回对象自身的所有可枚举属性值的数组
          yield* Object.values(this);//和下行两种写法输出结果相同
          yield* [this.hobbies];
        },
      };
      for(const item of obj){
        console.log(item);
      }
    </script>

4.Symbol

一种基本的数据类型,Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。

Symbol不支持语法new Symbol();

4.1每个从Symbol返回的值都是唯一的,如有需要可以使用new Object(Symbol())

  <body>
    <script>
      let s1 = Symbol(1);
      let s2 = Symbol(1);
      //let s3 = new Symbol();//报错。不允许直接实例化
      console.log(s1 == s2);//false//产生一个唯一的值和其他值不等,和自身相等
      //把Symbol转换成对象
      let s4 = new Object(s1);
      console.log(s1,typeof s1);
      console.log(s4,typeof s4);
    </script>

4.2全局共享的Symbol 

Symbol.for()用于全局注册Symbol,存在则取值,不存在则创建

Symbol.keyFor()用于获取全局注册的Symbol的key

    <script>
      //键位a的Symbol值,是否存在全局注册表中,不存在则创建
    let s1 = Symbol.for('a');//创建
    let s2 = Symbol.for('b');
    let s3 = Symbol.for('c');
    console.log(s1,s2,s3);//Symbol(a) Symbol(b) Symbol(c)

    //键位a的Symbol值是否存在全局注册表中,存在则取值,返回Symbol值
    let s4 = Symbol.for('a');
    console.log(s4 == s1);//ture
    //根据Symbol 值获取key值
    let k1 = Symbol.keyFor(s1);
    console.log(k1);//a
    </script>

4.3内置的Symbol属性应用

Symbol.iterator用于定义对象的默认遍历器

Symbol.hasInstance用于判断对象是否为某个机构赞函数的事例

Symbol.isConcatSpreadable用于判断对象是否可以展开

    <script>
      let arr1 = [1,2,3,4,5];
      let arr2 = ['a','b','c','d','e'];
      // let arr3 = arr1.concat(arr2);
      // console.log(arr3);//[1, 2, 3, 4, 5, 'a', 'b', 'c', 'd', 'e']
      arr2[Symbol.isConcatSpreadable] = false;//关闭展开
      let arr3 = arr1.concat(arr2);
      console.log(arr3);//[1, 2, 3, 4, 5, Array(5)]
    </script>

Symbol.spacies用于指定对象的构造函数

Symbol.split指向一个正则表达式的索引处分割字符串的方法,这个方法通过String.prototype.split()​​​​​​​调用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴椰啵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值