55个JS代码让你轻松当大神

本文从简单到复杂列出了前端常用的一些代码段。善用这些代码可以让你的代码更高雅,别人更难懂。你就是公司的护城河,你就是前端的顶梁柱。

  1. 数组平铺。这是一个很实用的让复杂的数组快速变成一个常用数组的技巧。arr参数不管是一维数组还是多维数组,经过转变之后最终都会变成一维数组。
  1. 手动延时xx毫秒。在异步请求编程中,有时候要用到让进程等待的情况,用这个函数可以设定等待多少毫秒。
  1. 把数组内容随便换个位置。可以用来生成随机位置的内容,比如洗牌这种场景。
  1. 数组去重。原理就是先转成Set对象,自动去掉重复的部分,再转回数组。
  1. 一键给网页上边框。常用于调试的时候,看一下DOM的框是不是自己要的,其中颜色是随机生成的。也可以自己改一下变成固定颜色的边框。

效果如下:

6. 一键查看密码。同理也可以自己修改,这里用代码的方式来查看。原理是input框虽然是type=password的,但是内容并没有加密,只要换成text就会正常显示。

  1. 一键去掉鼠标的图标,让人摸不着头脑的操作。一般用于防止别人调试自己的网页。
  1. 检查一个日期是否是在周末。常用于判断当前日期是否是周末,一般场景下还会叠加一个判断是否节假日。
  1. 检查一个日期是否在某个年份内。通过获取参数日期的年和需要比较的日期的年来进行比较。如果年的参数比较规范,可以不转一次Date对象,直接比较即可。
  1. 检查日期是否是一个有效日期。原理是用参数来创建日期,看日期是否有效。
  1. 计算两个日期之间的时间间隔。这里计算的是天,也可以自己改成其他的。
  1. 获取日期从年初到现在入参有多少天。入参是Date对象,通过比较获得时间差,默认是毫秒。这里除以一天的毫秒数获得了天数。
  1. 返回日期的时间部分,并设置格式为hh:mm:ss的形式。
  1. 把字符串的首字母大写。有时候网页展示的时候会用得到。
  1. 字符串反转。一般没啥用,看看就行。以前面试的时候会用的到。
  1. 生成随机字符串,各种随机基本都是这个原理。
  1. 按照参数阶段字符串的长度,如果长度不够就不截取。一般代码中自己写也行,但是要多写一个逻辑判断。
  1. 删除字符串中的HTML内容。一般情况下用来防止富文本内容中注入了js代码、去掉不需要的内容等。
  1. 判断一个数组是否为空。这里一方面是判断是否为数组,另一方面是判断数组内容。
  1. 数组合并,两个数组合并成一个数组。下面是两种方法,都有用,只是用到的语法不同。
  1. 判断数字是奇数还是偶数,同理还可以判断是否可以被3整除之类的。
  1. 计算一组数字的平均值。具体就是所有数字相加再被数量除一次。
  1. 获得一个随机数。第一个是从0开始到数字之间,第二个是两个数字之间。注意最后的加法是独立算数,修改的时候别改错地方了。
  1. 按照指定位数四舍五入。如果没有要求,第二种也是很好用的。
  1. 获取一个随机颜色。
  1. 使用浏览器的原生API复制内容到剪贴板。有的浏览器可能有兼容问题。
  1. 清除Cookie。老方法了,可以挨个清除cookie的内容。
  1. 使用浏览器原生的API获得用户框选的文本内容。
  1. 检查当前环境是否黑暗模式。CSS的检查也是这个原理。

30.让页面返回浏览器顶部。

  1. 检测当前标签页是否处于激活模式。
  1. 检测当前设备是否苹果设备。同理还有微信浏览器、支付宝浏览器等。
  1. 判断当前页面是否在底部了。
  1. 打开浏览器的打印模式。
  1. 检测一个对象是否为空。
  1. 前端自己生成18位的UUID。用到的时候就用到了,一般情况下用不到,哈哈。
  1. RGB形式的颜色转成16进制的颜色。
  1. HEX形式的颜色转RGB形式的颜色。
  1. 网易音乐的web端启用下载功能(标准音质)。
  1. 前端自己计算内容的SHA256值。
  1. 浅拷贝。简单使用场景下的方式。
  1. 深拷贝。多层级下的内容都可以处理到。function不行,那个要单独处理。
  1. 自己实现一个单向链表。面试的时候会用到,一般情况下有这个思维就可以了。
  1. 自定义方式的数组排序。
  1. useMap。实现一个自动处理Map对象的hook。
  1. useSet。实现一个自动处理内部数据的Set对象。
  1. useDefault。有内容使用设置的内容,没有内容使用默认的内容。
  1. useMergeState。实现一个合并内容的对象,常见对象的自动更新。
  1. useDebounce。实现一个React的防抖。
  1. useForm。实现一个React的Form对象,自动管理Form内容。
  1. useEventListener。实现一个自动监听函数,可以监听鼠标移动。
  1. useKeyPress。实现一个键盘对应的键的事件监听函数。
  1. useHover。实现一个鼠标悬停事件的监听函数。
  1. useRequestAnimationFrame。实现一个RequestAnimationFrame函数在React中使用的方法。
  1. useBodyScrollLock。实现一个自动锁定滚动条的函数。一般弹窗会用的上。

一个在线制作动态数据竞赛的网站,无需代码知识轻松搞定

之前介绍过如何通过github上D3.js项目实现动态数据排名,但是,对于没有html代码相关知识的朋友并不友好,现在好了,站长找到一个可以不用代码数据,只需要会用excel表格就可以了,分享给大家,于是就有了今天这篇文章。

https://app.flourish.studio/

  • 打开上方链接,先注册,注册后进入后台,如下图所示。
  • 点击新建,下拉,选择动态数据竞赛模式,如下图所示。
  • 进入编辑状态后,点击数据(Data),根据表格形式,在桌面新建一个空白表格,之后将表格内的所有内容,全部复制粘贴到其中,如下图所示。
  • 至于获取数据,这就需要自己想办法喽,将里面的内容都替换后,在上传到后台,如下图所示,之后再看preview,预览就可以了,这样数据就动起来了。
  • 右侧就是样式的修改了,诸如单位,大小等等,看自己喜好,如果制作完成,就可以点击右上角生成,会生成一个预览链接,点击它查看即可,如下图所示。
  • 看一下自己做的成果,是不是很有成就感?
  • 制作成视频就更简单了,只需要用录屏应用将整个过程录下来,随后在pr里面剪辑,配音,一个完整的数据动态排名就出现了。

200行JS代码,带你实现代码编译器

转载链接:https://juejin.im/post/5e802e41e51d4546b659b31b

先问大家一句,日常项目开发中你能离开 ES6 吗?

一、前言

对于前端同学来说,编译器可能适合神奇的魔盒,表面普通,但常常给我们惊喜。编译器,顾名思义,用来编译,编译什么呢?当然是编译代码咯。

其实我们也经常接触到编译器的使用场景:

  • React 中 JSX 转换成 JS 代码;
  • 通过 Babel 将 ES6 及以上规范的代码转换成 ES5 代码;
  • 通过各种 Loader 将 Less / Scss 代码转换成浏览器支持的 CSS 代码;
  • 将 TypeScript 转换为 JavaScript 代码。
  • and so on…

使用场景非常之多,我的双手都数不过来了。虽然现在社区已经有非常多工具能为我们完成上述工作,但了解一些编译原理是很有必要的。接下来进入本文主题:「200行JS代码,带你实现代码编译器」

二、编译器介绍

现代程序主要有两种编译模式:静态编译和动态解释。推荐一篇文章《Angular 2 JIT vs AOT》介绍得非常详细。

简称 「AOT」(Ahead-Of-Time)即 「提前编译」 ,静态编译的程序会在执行前,会使用指定编译器,将全部代码编译成机器码。

(图片来自:https://segmentfault.com/a/1190000008739157) 在 Angular 的 AOT 编译模式开发流程如下:

  • 使用 TypeScript 开发 Angular 应用
  • 运行 ngc 编译应用程序 使用 Angular Compiler 编译模板,一般输出 TypeScript 代码运行 tsc 编译 TypeScript 代码
  • 使用 Webpack 或 Gulp 等其他工具构建项目,如代码压缩、合并等
  • 部署应用

简称 「JIT」(Just-In-Time)即 「即时编译」 ,动态解释的程序会使用指定解释器,一边编译一边执行程序。

(图片来自:https://segmentfault.com/a/1190000008739157[1]) 在 Angular 的 JIT 编译模式开发流程如下:

  • 使用 TypeScript 开发 Angular 应用
  • 运行 tsc 编译 TypeScript 代码
  • 使用 Webpack 或 Gulp 等其他工具构建项目,如代码压缩、合并等
  • 部署应用

「AOT 编译流程:」

(图片来自:segmentfault.com/a/119000000…)

「JIT 编译流程:」

(图片来自:segmentfault.com/a/119000000…)

特性 AOT JIT 编译平台 (Server) 服务器 (Browser) 浏览器 编译时机 Build (构建阶段) Runtime (运行时) 包大小 较小 较大 执行性能 更好 – 启动时间 更短 –

除此之外 AOT 还有以下优点:

  • 在客户端我们不需要导入体积庞大的 angular 编译器,这样可以减少我们 JS 脚本库的大小
  • 使用 AOT 编译后的应用,不再包含任何 HTML 片段,取而代之的是编译生成的 TypeScript 代码,这样的话 TypeScript 编译器就能提前发现错误。总而言之,采用 AOT 编译模式,我们的模板是类型安全的。

摘抄维基百科中对 编译器[2]工作流程介绍:

一个现代编译器的主要工作流程如下: 源代码(source code)→ 预处理器(preprocessor)→ 编译器(compiler)→ 汇编程序(assembler)→ 目标代码(object code)→ 链接器(linker)→ 可执行文件(executables),最后打包好的文件就可以给电脑去判读运行了。

这里更强调了编译器的作用:「将原始程序作为输入,翻译产生目标语言的等价程序」

The Super Tiny Compiler编译器工作流程.png

编译器三个核心阶段.png

目前绝大多数现代编译器工作流程基本类似,包括三个核心阶段:

  1. 「解析(Parsing)」 :通过词法分析和语法分析,将原始代码字符串解析成「抽象语法树(Abstract Syntax Tree)」
  2. 「转换(Transformation)」:对抽象语法树进行转换处理操作;
  3. 「生成代码(Code Generation)」:将转换之后的 AST 对象生成目标语言代码字符串。

三、编译器实现

本文将通过 「The Super Tiny Compiler[3]」 源码解读,学习如何实现一个轻量编译器,最终「实现将下面原始代码字符串(Lisp 风格的函数调用)编译成 JavaScript 可执行的代码」

Lisp 风格(编译前) JavaScript 风格(编译后) 2 + 2 (add 2 2) add(2, 2) 4 – 2 (subtract 4 2) subtract(4, 2) 2 + (4 – 2) (add 2 (subtract 4 2)) add(2, subtract(4, 2))

话说 The Super Tiny Compiler 号称「可能是有史以来最小的编译器」,并且其作者 James Kyle 也是 Babel 活跃维护者之一。

让我们开始吧~

现在对照前面编译器的三个核心阶段,了解下 The Super Tiny Compiler 编译器核心工作流程:

「图中详细流程如下:」

  1. 执行「入口函数」,输入「原始代码字符串」作为参数;
  1. 进入「解析阶段(Parsing)」,原始代码字符串通过「词法分析器(Tokenizer)「转换为」词法单元数组,「然后再通过 「词法分析器(Parser)「将」词法单元数组」转换为」抽象语法树(Abstract Syntax Tree 简称 AST)」,并返回;
  1. 进入「转换阶段(Transformation)」,将上一步生成的 「AST 对象」 导入「转换器(Transformer)」,通过「转换器」中的「遍历器(Traverser)」,将代码转换为我们所需的「新的 AST 对象」
  1. 进入「代码生成阶段(Code Generation)」,将上一步返回的「新 AST 对象」通过「代码生成器(CodeGenerator)」,转换成 「JavaScript Code」
  1. 「代码编译结束」,返回 「JavaScript Code」

上述流程看完后可能一脸懵逼,不过没事,请保持头脑清醒,先有个整个流程的印象,接下来我们开始阅读代码:

首先定义一个入口方法 compiler ,接收原始代码字符串作为参数,返回最终 JavaScript Code:

在解析阶段中,我们定义「词法分析器方法」 tokenizer 和「语法分析器方法」 parser 然后分别实现:

「词法分析器方法」 tokenizer 的主要任务:遍历整个原始代码字符串,将原始代码字符串转换为「词法单元数组(tokens)」,并返回。在遍历过程中,匹配每种字符并处理成「词法单元」压入「词法单元数组」,如当匹配到左括号( ( )时,将往「词法单元数组(tokens)「压入一个」词法单元对象」({type: \’paren\’, value:\'(\’})。

「语法分析器方法」 parser 的主要任务:将「词法分析器」返回的「词法单元数组」,转换为能够描述语法成分及其关系的中间形式(「抽象语法树 AST」)。

在转换阶段中,定义了转换器 transformer 函数,使用词法分析器返回的 LISP 的 AST 对象作为参数,将 AST 对象转换成一个新的 AST 对象。 为了方便代码组织,我们定义一个遍历器 traverser 方法,用来处理每一个节点的操作。

在看「遍历器」 traverser 方法时,建议结合下面介绍的「转换器」 transformer 方法阅读:

重要一点,这里通过 _context 引用来「维护新旧 AST 对象」,管理方便,避免污染旧 AST 对象。

接下来到了最后一步,我们定义「代码生成器」 codeGenerator 方法,通过递归,将新的 AST 对象代码转换成 JavaScript 可执行代码字符串。

截止上一步,我们完成简易编译器的代码开发。接下来通过前面原始需求的代码,测试编译器效果如何:

总结 The Super Tiny Compiler 编译器整个工作流程:「1、input => tokenizer => tokens」「2、tokens => parser => ast」「3、ast => transformer => newAst」「4、newAst => generator => output」

其实多数编译器的工作流程都大致相同:

四、手写 Webpack 编译器

根据之前介绍的 The Super Tiny Compiler编译器核心工作流程,再来手写 Webpack 的编译器,会让你有种众享丝滑的感觉~

话说,有些面试官喜欢问这个呢。当然,手写一遍能让我们更了解 Webpack 的构建流程,这个章节我们简要介绍一下。

从启动构建到输出结果一系列过程:

  1. 「初始化参数」

解析 Webpack 配置参数,合并 Shell 传入和 webpack.config.js 文件配置的参数,形成最后的配置结果。

  1. 「开始编译」

上一步得到的参数初始化 compiler 对象,注册所有配置的插件,插件监听 Webpack 构建生命周期的事件节点,做出相应的反应,执行对象的 run 方法开始执行编译。

  1. 「确定入口」

从配置的 entry 入口,开始解析文件构建 AST 语法树,找出依赖,递归下去。

  1. 「编译模块」

递归中根据「文件类型」「loader 配置」,调用所有配置的 loader 对文件进行转换,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。

  1. 「完成模块编译并输出」

递归完事后,得到每个文件结果,包含每个模块以及他们之间的依赖关系,根据 entry 配置生成代码块 chunk 。

  1. 「输出完成」

输出所有的 chunk 到文件系统。 注意:在构建生命周期中有一系列插件在做合适的时机做合适事情,比如 UglifyPlugin 会在 loader 转换递归完对结果使用 UglifyJs 压缩「覆盖之前的结果」

手写 Webpack 需要实现以下三个核心方法:

  • createAssets : 收集和处理文件的代码;
  • createGraph :根据入口文件,返回所有文件依赖图;
  • bundle : 根据依赖图整个代码并输出;

五、总结

本文从编译器概念和基本工作流程开始介绍,然后通过 The Super Tiny Compiler 译器源码,详细介绍核心工作流程实现,包括「词法分析器」「语法分析器」「遍历器」「转换器」的基本实现,最后通过「代码生成器」,将各个阶段代码结合起来,实现了这个号称「可能是有史以来最小的编译器。」本文也简要介绍了「手写 Webpack 的实现」,需要读者自行完善和深入哟! 是不是觉得很神奇~

当然通过本文学习,也仅仅是编译器相关知识的边山一脚,要学的知识还有非常多,不过好的开头,更能促进我们学习动力。加油! 最后,文中介绍到的代码,我存放在 Github 上:

  1. [learning]the-super-tiny-compiler.js[4]
  2. [writing]webpack-compiler.js[5]

作者博客:www.pingan8787.com

github: https://github.com/pingan8787/Leo_Reading/issues

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。