【源码阅读】arrify的探索

132 阅读4分钟

准备代码

这里就不细说了,上一篇文章 【源码阅读】omitjs源码的初步体验 - 掘金 (juejin.cn)写过,下面的文章这一步也不会再写了,代码拉到本地后我自己总是会忘了npm i或者yarn,这里提醒一下自己,

先看看package.json中的devDependencies

"devDependencies": {
    "ava": "^3.15.0",//测试工具
    "tsd": "^0.14.0",//该工具允许您`.d.ts`通过创建带有`.test-d.ts`扩展名的文件来为您的类型定义(即您的文件)编写测试
    "xo": "^0.39.1"//这个没看懂是干嘛的
}

关于代码调试

  1. 重新再学习一遍代码调试 新手向:前端程序员必学基本技能——调试JS代码 - 掘金 (juejin.cn) 写上一篇文章没看懂,用了个比较笨的方法学习的omit.js库,这一次按这个文章走一遍
  2. 关于vscode调试代码,又找到一篇很详尽的文章-手把手带你会习VSCode debug,不信你还不会!-VSCode-PHP中文网,这篇文章可以时不时的拿出来看看

之前工作去只用console.log来调试,没有尝试过别的方法,参加源码共读后发现,console.log大法应用范围太窄了,也略显笨拙(对于我自己来说哦),对于阅读源码来说,应该多用用vscode自带的debug功能

源码

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

Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for...of循环使用。当需要对一个对象进行迭代时(比如开始用于一个for..of循环中),它的@@iterator方法都会在不传参情况下被调用,返回的迭代器用于获取要迭代的值。

说实话,我没看懂

什么是Symbol以及它的特点

symbol是es6新增类型,特点如下:

  1. symbol属性值对应的值是唯一的,这解决了命名冲突的问题,类似于id的作用。
  2. symbol值不能与其他数据进行计算,包括与字符串拼接。
  3. for/in ,for/of遍历时不会遍布symbol属性
Iterotor是什么

Iterator是一个遍历器的接口,是部署在数据结构上的,很多数据结构原生具备Iterator接口,这就意味着,我们不需要任何处理就可以使用for/of了,拥有symbol.Iterator属性返回的对象,都会在使用for/of时被当作Iterator接口当这个对象符合Iterator接口的标准时,for/of就可以完成任务,不符合就会报错。

symbol的内置符号symbol.Iterator,有什么用?

这个符号可以是任意对象上的一个专门属性,语言机制会自动的在这个属性上寻找一个方法,这个方法会构造一个迭代器来迭代这个对象的值,这个方法就是next方法,...展开和for/of循环会自动使用它,我们可以自定义symbol.iterator属性为任意对象值定义自己的迭代器逻辑,他将覆盖默认的迭代器。相当于是定义了一种元编程行为,提供给Javascript其他部分(也就是运算符和循环结构)在处理定义的对象时使用。

在Js中迭代器对象实现了可迭代协议,迭代器对象由Symbol.iterator属性的值返回。 Symbol.iterator属性的值是一个函数,它返回一个迭代器对象。 迭代器指的是拥有next方法的对象。 该next方法必须返回一个带有value和done的对象。

为什么会出现for..of?

为了理解条件语句,我们曾想象JavaScript解释器在源代码中会经过不同路径。而循环语句则是把这些路径弯曲又折回起点,以重复执行代码中的某部分。

es6定义了一个新循环语句:for/of。这种新循环虽然使用for关键字,但它们是完全不一同的两种循环,你说和for/in像不像?为什么?

for/of循环是专门用于可迭代对象的,什么是可迭代对象呢?

我们前文提到具有symbol.iterator属性的对象就是可以迭代的。而这个对象就是可迭代对象。

对象本身默认是不可迭代的。运行时尝试对常规对象使用for/of会抛出TypeError.

部分内容引自-Symbol.Iterator简单理解_牧之说前端的博客-CSDN博客_symbol.iterator

写到这里,总结一下:

  1. {} 对象是没有symbol.iterator 属性的,所以用for/of会报错,可手动实现一下或用for/in
  2. 数组,set map 是可以for/of的