【若川视野 x 源码共读】第33期 | arrify 转数组

55 阅读1分钟

学习来自blog.csdn.net/qq_19901795…

blog.csdn.net/weixin_3925…

juejin.cn/post/710021…

源代码

export default function arrify(value) {
	if (value === null || value === undefined) {
		return [];
	}

	if (Array.isArray(value)) {
		return value;
	}

	if (typeof value === 'string') {
		return [value];
	}

	if (typeof value[Symbol.iterator] === 'function') {
		return [...value];
	}

	return [value];
}

Symbol.iterator 迭代器,

Symbol .iterator属性是一个函数。

原生支持迭代器的数据结构:Array、Map、Set、String、TypedArray、函数的arguments对象、NodeList对象。

let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();
 
iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }

解构赋值默认调用迭代器

let set = new Set().add('a').add('b').add('c');
 
let [x,y] = set;
// x='a'; y='b'
 
let [first, ...rest] = set;
// first='a'; rest=['b','c'];

扩展运算符默认调用迭代器

// 例一
var str = 'hello';
[...str] //  ['h','e','l','l','o']
 
// 例二
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']

yield* 生成器默认使用迭代器

let generator = function* () {
  yield 1;
  yield* [2,3,4];
  yield 5;
};
 
var iterator = generator();
 
iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }

其他

  • for...of(能遍历数组,不能遍历对象,是因为Object默认没有迭代器行为,不清楚Object上的属性的先后顺序。)
  • Array.from()
  • Map(),Set(),weakMap(),WeakSet()
  • Promise.all()
  • Promise.race

使用for...of 对对象遍历

const info = {
  today: "2022-6-11",
  weather: "rain",
  emperature: "26摄氏度"
}
Object.defineProperty(info, Symbol.iterator, {
  enumberable: false,
  configurable: false,
  writable: false,
  value() {
    const that = this
    let index = -1
    const key = Object.keys(that)
    return {
      next() {
        index++
        return {
          value: that[key[index]],
          done: index + 1 > key.length
        }
      }
    }
  }
})

for (const data of info) {
  console.log(data)
}

总结:对迭代器和迭代对象的写法有了一个新的理解。