es6——解构赋值 、for of 的 Iterator 遍历器

解构赋值

ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)

  1. 基本用法
	{
        let name = 'bob', age = 18, sex = 'man';
        console.log(name, age, sex);// bob 18 man
    }
    {
        let [name, age, sex] = ['bob', 18, 'man'];
        name='lucy';
        console.log(name, age, sex);// lucy 18 man
    }
    {
		let [...rest] = ['bob', 18, 'man'];
		console.log(rest); // [ 'bob', 18, 'man' ]
	}
  1. 对象的解构赋值
    {
        let {name, age, sex} = {name: 'bob', age: 18, sex: 'man'};
        console.log(name, age, sex);// bob 18 man
    }
    //复杂对象解构赋值
    {
        let {name, age, sex, friends, pet} = {
            name: 'john',
            age: 18,
            sex: 'man',
            friends: ['bob', 'lucy'],
            pet: {name: 'dog', age: 4}
        };
        console.log(name, age, sex, friends,pet);// john 18 man (2) ["bob", "lucy"] {name: "dog", age: 4}
    }
    {
	    let { ...rest } = {
		    name: 'john',
		    age: 18,
		    sex: 'man',
		    friends: ['bob', 'lucy'],
			pet: { name: 'dog', age: 4 }
		};
		console.log(rest); // { name: 'john', age: 18, sex: 'man', friends: [ 'bob', 'lucy' ], pet: { name: 'dog', age: 4 } }
    }
  1. 数组解构赋值
    {
        let [name, age, sex] = ['bob', 18, 'man'];
        name = 'lucy';
        console.log(name, age, sex);// lucy 18 man
    }
    //复杂对象解构赋值
    {
        let [arr1, [arr2, arr3, [arr4, arr5]]] = [1, [2, 3, [4, 5]]];
        console.log(arr1, arr2, arr3, arr4, arr5);// 1 2 3 4 5
    }
    {
        let [arr]=[];
        console.log(arr);//undefined
    }
    {
        let [a,,b,c]=[1,2,3];
        console.log(a, b, c);// 1 3 undefined
    }
  1. 基本类型的解构赋值(实际应用比较少)
    {
        let [a,b,c,d,e]='bob';
        console.log(a, b, c, d, e);// b o b undefined undefined
    }
    {
        let [a,b,c,d,e]=12345;
        console.log(a, b, c, d, e);// error: 12345 is not iterable(number类型没有构造器 string类型有构造器)
    }
用途
  1. 交换变量的值
  let [x, y] = [1, 2];
  [x, y] = [y, x]
  console.log(x, y)// 2 1
  1. 从函数返回多个值
  // 返回数组
  function f1 () {
    return [1, 2, 3]
  }
  let [a, b, c] = f1()
  console.log(a, b, c)// 1 2 3

  // 返回对象
  function f2 () {
    return {
      foo: 1,
      bar: 2
    }
  }
  let { foo, bar } = f2()
  console.log(foo, bar)// 1 2
  1. 函数参数的定义
  // 参数是一组有次序的值
  function f1 ([x, y, z]) { ... }
  f1([1, 2, 3])

  // 参数是一组无次序的值
  function f2 ({ x, y, z }) { ... }
  f2({ z: 3, x: 1, y: 2 })
  1. 提取 JSON 数据
  let json = {
    name: 'john',
    age: 18,
    gender: '男',
    hobbies: ['游戏', '追剧']
  }

  let { name, age, gender, hobbies } = json
  console.log(name, age, gender, hobbies)// john 18 男 ["游戏", "追剧"]
  1. 遍历 Map 结构
  let map = new Map()
  map.set('bob', 12)
  map.set('lucy', 22)

  for (let [key, value] of map) {
    console.log(key + ' is ' + value)
  }
  // bob is 12
  // lucy is 22

  // 如果想单独遍历
  // 键名
  for (let [key]of map) {
    console.log(key)// bob lucy
  }
  // 键值
  for (let [, value]of map) {
    console.log(value)
  }
  1. 输入模块的指定方法
  const { SourceMapConsumer, SourceNode } = require('source-map')

for of

  • for … of:遍历获取键值,无法直接遍历对象
  • for … in:遍历获取键名,可以直接遍历对象,获取键名
  let obj = ['a', 'b', 'c']
  
  for (let i of obj) {
    console.log(i)// a  b  c
  }
  
  for (let i in obj) {
    console.log(i)// 0  1  2
  }
  
  // 针对 for ... of 无法遍历对象,用 Object.keys() 将对象的键名生成一个数组,再遍历
  let obj = { a: '1', b: '2', c: '3' }
  
  for (let i in obj) {
    console.log(i)// a  b  c
  }
  
  for (let i of Object.keys(obj)) {
    console.log(i)// a  b  c
  }

  // 或者自己封装遍历对象
  function * f1 (obj) {
    let keys = Reflect.ownKeys(obj)
    for (let key of keys) {
      yield [key, obj[key]]
    }
  }

  let obj = { a: '1', b: '2', c: '3' }

  for (let [key, value] of f1(obj)) {
    console.log(key, value)
  }
  
  // 另一种写法:将 Generator 函数添加到对象的 Symbol.iterator 属性上
  function * f1 () {
    let keys = Object.keys(this)

    for (let key of keys) {
      yield [key, this[key]]
    }
  }

  let obj = { a: '1', b: '2', c: '3' }
  obj[Symbol.iterator] = f1

  for (let [key, value] of obj) {
    console.log(key, value)
  }

遍历具有 Iterator 接口的数据结构,原生具备 Iterator 接口的数据结构如下

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

Iterator 基本原理:调用 next 方法访问并返回数据结构的当前成员信息,具体就是返回具备 value 和 done 两个属性的对象,value 是当前成员的值,done 是布尔类型表示遍历是否结束

基本原理:

  let it = Iterator(['a', 'b'])

  console.log(it.next())// {value: "a", done: false}
  console.log(it.next())// {value: "b", done: false}
  console.log(it.next())// {value: undefined, done: true}

  function Iterator (arr) {
    let nextIndex = 0
    return {
      next: function () {
        return nextIndex < arr.length ?
          { value: arr[nextIndex++], done: false } :
          { value: undefined, done: true }
      },
    }
  }

Iterator 接口:

  function Obj (value) {
    this.value = value
    this.next = null
  }

  Obj.prototype[Symbol.iterator] = function () {
    let iterator = { next }
    let current = this

    function next () {
      if (current) {
        let value = current.value
        current = current.next
        return { done: false, value: value }
      } else {
        return { done: true }
      }
    }

    return iterator
  }

  let one = new Obj(1)
  let two = new Obj(2)
  let three = new Obj(3)

  one.next = two
  two.next = three

  for (let i of one) {
    console.log(i)// 1  2  3
  }
数组的 iterator 接口
  let arr = {
    data: ['a', 'b', 'c'],
    [Symbol.iterator] () {
      const self = this
      let index = 0
      return {
        next () {
          if (index < self.data.length) {
            return {
              value: self.data[index++],
              done: false,
            }
          } else {
            return { value: undefined, done: true }
          }
        },
      }
    },
  }

  for (let i of arr) {
    console.log(i)// a  b  c
  }
伪数组的 iterator 接口

对于伪数组的对象,部署 Iterator 接口有个简便方法,即使用 Symbol.iterator 方法直接引用数组的 Iterator 接口

  NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]
  // 或者
  NodeList.prototype[Symbol.iterator] = [][Symbol.iterator]

实例:

  let pseudo_arr1 = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3,
    [Symbol.iterator]: [][Symbol.iterator],
  }

  for (let i of pseudo_arr1) {
    console.log(i)// a  b  c
  }

  // 注意:普通对象部署无效
  let pseudo_arr2 = {
    a: 'a',
    b: 'b',
    c: 'c',
    length: 3,
    [Symbol.iterator]: [][Symbol.iterator],
  }

  for (let i of pseudo_arr2) {
    console.log(i)// undefined  undefined  undefined
  }
字符串的 Iterator 接口
  let str = 'hello'
  let iterator = str[Symbol.iterator]()
  console.log(iterator.next())// {value: "h", done: false}
  console.log(iterator.next())// {value: "e", done: false}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值