55个JS代码让你轻松当大神
本文从简单到复杂列出了前端常用的一些代码段。善用这些代码可以让你的代码更高雅,别人更难懂。你就是公司的护城河,你就是前端的顶梁柱。
- 数组平铺。这是一个很实用的让复杂的数组快速变成一个常用数组的技巧。arr参数不管是一维数组还是多维数组,经过转变之后最终都会变成一维数组。
- 手动延时xx毫秒。在异步请求编程中,有时候要用到让进程等待的情况,用这个函数可以设定等待多少毫秒。
- 把数组内容随便换个位置。可以用来生成随机位置的内容,比如洗牌这种场景。
- 数组去重。原理就是先转成Set对象,自动去掉重复的部分,再转回数组。
- 一键给网页上边框。常用于调试的时候,看一下DOM的框是不是自己要的,其中颜色是随机生成的。也可以自己改一下变成固定颜色的边框。
效果如下:
6. 一键查看密码。同理也可以自己修改,这里用代码的方式来查看。原理是input框虽然是type=password的,但是内容并没有加密,只要换成text就会正常显示。
- 一键去掉鼠标的图标,让人摸不着头脑的操作。一般用于防止别人调试自己的网页。
- 检查一个日期是否是在周末。常用于判断当前日期是否是周末,一般场景下还会叠加一个判断是否节假日。
- 检查一个日期是否在某个年份内。通过获取参数日期的年和需要比较的日期的年来进行比较。如果年的参数比较规范,可以不转一次Date对象,直接比较即可。
- 检查日期是否是一个有效日期。原理是用参数来创建日期,看日期是否有效。
- 计算两个日期之间的时间间隔。这里计算的是天,也可以自己改成其他的。
- 获取日期从年初到现在入参有多少天。入参是Date对象,通过比较获得时间差,默认是毫秒。这里除以一天的毫秒数获得了天数。
- 返回日期的时间部分,并设置格式为hh:mm:ss的形式。
- 把字符串的首字母大写。有时候网页展示的时候会用得到。
- 字符串反转。一般没啥用,看看就行。以前面试的时候会用的到。
- 生成随机字符串,各种随机基本都是这个原理。
- 按照参数阶段字符串的长度,如果长度不够就不截取。一般代码中自己写也行,但是要多写一个逻辑判断。
- 删除字符串中的HTML内容。一般情况下用来防止富文本内容中注入了js代码、去掉不需要的内容等。
- 判断一个数组是否为空。这里一方面是判断是否为数组,另一方面是判断数组内容。
- 数组合并,两个数组合并成一个数组。下面是两种方法,都有用,只是用到的语法不同。
- 判断数字是奇数还是偶数,同理还可以判断是否可以被3整除之类的。
- 计算一组数字的平均值。具体就是所有数字相加再被数量除一次。
- 获得一个随机数。第一个是从0开始到数字之间,第二个是两个数字之间。注意最后的加法是独立算数,修改的时候别改错地方了。
- 按照指定位数四舍五入。如果没有要求,第二种也是很好用的。
- 获取一个随机颜色。
- 使用浏览器的原生API复制内容到剪贴板。有的浏览器可能有兼容问题。
- 清除Cookie。老方法了,可以挨个清除cookie的内容。
- 使用浏览器原生的API获得用户框选的文本内容。
- 检查当前环境是否黑暗模式。CSS的检查也是这个原理。
30.让页面返回浏览器顶部。
- 检测当前标签页是否处于激活模式。
- 检测当前设备是否苹果设备。同理还有微信浏览器、支付宝浏览器等。
- 判断当前页面是否在底部了。
- 打开浏览器的打印模式。
- 检测一个对象是否为空。
- 前端自己生成18位的UUID。用到的时候就用到了,一般情况下用不到,哈哈。
- RGB形式的颜色转成16进制的颜色。
- HEX形式的颜色转RGB形式的颜色。
- 网易音乐的web端启用下载功能(标准音质)。
- 前端自己计算内容的SHA256值。
- 浅拷贝。简单使用场景下的方式。
- 深拷贝。多层级下的内容都可以处理到。function不行,那个要单独处理。
- 自己实现一个单向链表。面试的时候会用到,一般情况下有这个思维就可以了。
- 自定义方式的数组排序。
- useMap。实现一个自动处理Map对象的hook。
- useSet。实现一个自动处理内部数据的Set对象。
- useDefault。有内容使用设置的内容,没有内容使用默认的内容。
- useMergeState。实现一个合并内容的对象,常见对象的自动更新。
- useDebounce。实现一个React的防抖。
- useForm。实现一个React的Form对象,自动管理Form内容。
- useEventListener。实现一个自动监听函数,可以监听鼠标移动。
- useKeyPress。实现一个键盘对应的键的事件监听函数。
- useHover。实现一个鼠标悬停事件的监听函数。
- useRequestAnimationFrame。实现一个RequestAnimationFrame函数在React中使用的方法。
- 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
目前绝大多数现代编译器工作流程基本类似,包括三个核心阶段:
- 「解析(Parsing)」 :通过词法分析和语法分析,将原始代码字符串解析成「抽象语法树(Abstract Syntax Tree)」;
- 「转换(Transformation)」:对抽象语法树进行转换处理操作;
- 「生成代码(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 编译器核心工作流程:
「图中详细流程如下:」
- 执行「入口函数」,输入「原始代码字符串」作为参数;
- 进入「解析阶段(Parsing)」,原始代码字符串通过「词法分析器(Tokenizer)「转换为」词法单元数组,「然后再通过 「词法分析器(Parser)「将」词法单元数组」转换为」抽象语法树(Abstract Syntax Tree 简称 AST)」,并返回;
- 进入「转换阶段(Transformation)」,将上一步生成的 「AST 对象」 导入「转换器(Transformer)」,通过「转换器」中的「遍历器(Traverser)」,将代码转换为我们所需的「新的 AST 对象」;
- 进入「代码生成阶段(Code Generation)」,将上一步返回的「新 AST 对象」通过「代码生成器(CodeGenerator)」,转换成 「JavaScript Code」;
- 「代码编译结束」,返回 「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 的构建流程,这个章节我们简要介绍一下。
从启动构建到输出结果一系列过程:
- 「初始化参数」
解析 Webpack 配置参数,合并 Shell 传入和 webpack.config.js 文件配置的参数,形成最后的配置结果。
- 「开始编译」
上一步得到的参数初始化 compiler 对象,注册所有配置的插件,插件监听 Webpack 构建生命周期的事件节点,做出相应的反应,执行对象的 run 方法开始执行编译。
- 「确定入口」
从配置的 entry 入口,开始解析文件构建 AST 语法树,找出依赖,递归下去。
- 「编译模块」
递归中根据「文件类型」和 「loader 配置」,调用所有配置的 loader 对文件进行转换,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。
- 「完成模块编译并输出」
递归完事后,得到每个文件结果,包含每个模块以及他们之间的依赖关系,根据 entry 配置生成代码块 chunk 。
- 「输出完成」
输出所有的 chunk 到文件系统。 注意:在构建生命周期中有一系列插件在做合适的时机做合适事情,比如 UglifyPlugin 会在 loader 转换递归完对结果使用 UglifyJs 压缩「覆盖之前的结果」。
手写 Webpack 需要实现以下三个核心方法:
- createAssets : 收集和处理文件的代码;
- createGraph :根据入口文件,返回所有文件依赖图;
- bundle : 根据依赖图整个代码并输出;
五、总结
本文从编译器概念和基本工作流程开始介绍,然后通过 The Super Tiny Compiler 译器源码,详细介绍核心工作流程实现,包括「词法分析器」、「语法分析器」、「遍历器」和「转换器」的基本实现,最后通过「代码生成器」,将各个阶段代码结合起来,实现了这个号称「可能是有史以来最小的编译器。」本文也简要介绍了「手写 Webpack 的实现」,需要读者自行完善和深入哟! 是不是觉得很神奇~
当然通过本文学习,也仅仅是编译器相关知识的边山一脚,要学的知识还有非常多,不过好的开头,更能促进我们学习动力。加油! 最后,文中介绍到的代码,我存放在 Github 上:
- [learning]the-super-tiny-compiler.js[4]
- [writing]webpack-compiler.js[5]
作者博客:www.pingan8787.com
github: https://github.com/pingan8787/Leo_Reading/issues
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。