- 博客(90)
- 收藏
- 关注
原创 n个数字组成的字符串,移走k个字符,求剩下的字符组成的最小数字
这样转换意味着,每次操作的最优解,就是多次操作同时进行后的最优解(局部最优累积成为全局最优),需要对此进行证明,之后我们会使用严格的数学推导方式得出操作的规律,从而证明局部最优累积为全局最优;移走k个字符的情况,表达式中无非就是缺少了某些项,但跟移走1个字符的思路是一致的,规律是一致的,因此移走k个字符与移动k次,每次移走1个字符是等效的;移走k个字符,可以转换为移走1个字符,移k次,每一次都让剩下的字符组成的数字最小;给出n个数字组成的字符串,移走k个字符,求剩下的字符组成的最小数字;
2024-08-18 17:25:29 458
原创 理解Vue3的最长递增子序列算法
Vue3中使用了快速diff算法,有两个核心思想为了好理解,用返回最长递增子序列的算法来解释,而非原始的返回该子序列对应的在原数组中的索引值。
2024-08-18 17:21:12 1013
原创 避免CSRF攻击的方案
服务端下发用于CSRF token用于请求验证,客户端使用脚本进行请求时,携带该token进行验证,而恶意网站是无法获取到该token的值。这种方式要求token值一定要是随机生成。恶意网站发送对感兴趣网站的请求(或者正常网站发送恶意请求,但一般正常网站不可能这么做),显然,这肯定属于跨域请求了。使用表单让脚本自动提交的方式可以进行CSRF攻击。
2024-08-18 17:20:13 551
原创 如何判断给定值是否可以进行Proxy创建
对于immer.js v0.4.0版本,创建代理对象而言,目标对象仅限于Plain Object,因为immer.js要解决的问题就是plain object的数据更新问题,不解决原型链复杂的对象更新问题。在翻看immer.js的源码(v0.4.0)时,发现其中有一个方法用来判断给定值,是否可以创建代理对象,源码如下。, 最后交给ChatGPT来解释,gpt给的答案是源码写错了, 应该是判断。也是能创建出类似字面量对象那样的值,尝试如下代码。是能理解的,因为字面量的对象,原型就是。, 但是为什么要增加。
2024-08-18 17:17:33 133
原创 Chrome端口限制导致ERR_UNSAFE_PORT
普通用户没有使用1024以下端口号的权限,例如如果要使用80端口号,则必须是root用户权限才行。
2024-08-18 17:09:57 242
原创 封装Vue组件的一般流程
babel维护自己的Monorepo而开源的项目,用于管理和发布项目到GitHub和npm优化使用git和npm管理多包仓库的工作流工具管理具有多个包的JavaScript项目一键提交代码到git和npm仓库选择使用npm还是yarn来管理,需要单独配置在jest.config.js中配置。
2024-08-18 17:04:11 814
原创 异步网络请求竞态问题
很多场景下都存在异步网络请求的竞态问题,对于此类竞态问题,JavaScript本身不容易解决,需要借助一定的外部库更容易,如RxJS
2024-08-18 16:58:46 727
原创 module federation模块联邦与微前端
module federation是一种支持当前应用在运行时加载其他运行时应用内部模块的技术,在webpack配置时,当前应用需要用remote指定要加载的应用名称, 其他应用使用exposes指定对外暴露的内部模块,使用shared指定公共的共享模块。应用可以各自独立构建,独立部署,只在运行时产生耦合(加载)。各个应用在开发构建时都是独立的,降低了开发构建时的耦合性。
2024-07-24 17:36:17 1175
原创 (二叉)树的遍历
树,包括图,在遍历时都存在两种方式:深度优先遍历和广度优先遍历。树,一定有一个根节点,而图,没有根节点,但图中的任意节点都可以作为根节点使用(当然该节点一定要有边,否则没有意义)深度优先遍历访问当前节点将当前节点的children作为子树的根节点递归访问使用递归的方式// 传入树的根节点,开始深度优先遍历function dfs(root) { // 访问节点数据 console.log(root.val); if (root.children.length > 0) {
2021-06-11 18:31:00 264 1
原创 JavaScript数组拍平(扁平化)
数组扁平化指的是将多维数组转换为一维数组,实现的思路包含以下几种:拼接+递归拼接指的是新建一个空数组作为结果数组,将原数组进行分析变换后拼接到新数组上,最终返回新数组。递归指的是由于不知道多维数组嵌套有多少层,所以对原数组采用递归的分析方式来解决。通用的方式function flatten(arr) { let result = []; // 遍历数组元素,查看元素是否为数组类型 for (let i = 0; i < arr.length; i ++) { if (A
2021-06-09 21:39:18 488
原创 浏览器使用video播放m3u8类的直播流媒体
关于m3u8文件格式描述m3u8 是一种基于 HTTP Live Streaming 视频流媒体格式。m3u8文件本身是一个纯文本文件,用于存放整个视频的基本信息和分片(Segment)组成。由 Apple.inc 率先提出的 HLS 协议在 Mac 的 Safari 上原生支持,浏览器目前可以通过<video src="./test.m3u8" type="application/x-mpegURL">来播放。生成使用ffmpeg工具对mp4格式的视频进行基于hls协议分割可以得到m
2021-03-09 14:14:12 8532
原创 Next.js基本使用
Next.js创建项目使用命令 npm init next-app [your app name]页面路由系统创建页面:页面:放置在pages文件夹中的React组件,需要被默认导出组件文件中不需要手动引入React页面的URL地址与文件地址一一对应页面跳转Link组件:默认使用JavaScript进行跳转,即SPA形式,如果禁用了JavaScript,则使用<a>进行跳转引入:import Link from 'next/link'
2021-03-04 15:13:00 2417 1
原创 简易的打包器--webpack打包原理
手写一个简单的类似webpack的打包器打包流程说明:定义依赖分析函数,通过读取文件内容,分析得到该文件导入的依赖项code => AST => 得到导入声明,记录导入声明中的依赖项路径 => AST->code => 返回记录当前文件filename、依赖项dependencies和转译后的code的对象定义分析依赖图列表的函数,传入项目的入口文件,递归调用依赖分析函数,得到所有文件的依赖关系图列表,返回该列表。核心在于如何递归调用依赖分析函数,这里使用广
2021-02-23 20:39:53 332 2
原创 封装Vue组件库
封装Vue组件组件库开发很多项目都会用到界面和功能相似的组件,为了能在不同项目中最大程度重用组件,所以会进行组件库开发,以提供不同项目基础的组件开源组件库Element-UIiView组件驱动开发CDDComponent-Driven Development自下而上构建UI从组件开始,到页面结束:先隔离开发组件,再组合成页面组件最大程度重用并行开发可视化测试组件边界情况的处理组件可以访问$root属性,获取到当前组件树的根Vue实例,如果当前组件没有父实
2020-12-10 20:53:45 1243
原创 安装sharp包的注意事项
sharp包是基于node.js的高性能图片处理器在使用npm安装sharp的时候,需要注意以下问题使用镜像地址:npm config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp"npm config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"提前下载好sharp某版本号对应的libvips依赖包,放在np
2020-11-11 17:14:02 4017 2
原创 配置命令行启动应用程序
场景需求在命令行中启动应用程序是常见的需求,输入一个命令和路径,就可以在输入的路径下启动对应的应用程序,这样的方式很方便,免得去点击应用程序图标才能打开,类似于vscode的code命令。方法以下方式都针对Mac OS系统终端输入的命令会在$PATH环境变量下寻找,$PATH包含了几个目录,通常选择/usr/local/bin目录来存放新增的命令。方式一将应用程序的可执行文件链接到usr/local/bin目录下,这里以CocosCreator应用程序为例。打开Application目录,找
2020-11-05 20:52:55 839
原创 为其他仓库托管平台添加密钥
一般而言,除了在GitHub仓库外,很多公司习惯在GitLab上托管代码。因此,开发者通常会有多个密钥,分别为多个托管平台使用。参考资料生成新 SSH 密钥并添加到 ssh-agent生成密钥对使用如下命令生成一个SSH 密钥对ssh-keygen -t rsa -b 4096 -C "email@example.com"其中,- C标志是为了在密钥中添加注释,从而可以在众多的密钥中识别该密钥。输入密钥对的保存路径。如果不使用默认的路径(通常是~/.ssh/),则需要自定义路径,
2020-09-17 15:16:51 189
原创 服务端渲染SSR的原理与部署
SPA单页应用缺点首屏渲染时间长不利于SEO服务端渲染服务端执行前端框架代码,生成网页内容,返回客户端,客户端激活为SPA。现代化服务端渲染,或称为同构渲染,应用称为服务端渲染应用或同构应用什么是渲染把数据和模板拼接为完整的HTML文件传统服务端渲染数据渲染发生在服务端前后端耦合,不利于维护服务端压力大页面请求的数据量大,但模板中大多数字符都是多余的客户端渲染数据渲染发生在客户端首屏渲染慢:相比于服务端渲染且不带JavaScript脚本的情况加载JavaSc
2020-08-11 13:21:05 1168
原创 Vuex原理解读
组件内的状态管理状态管理流程状态管理state:驱动应用的数据源view:声明方式将state映射到视图actions:响应在view上的用户输入,导致的状态变化单向数据流组件之间通信方式父组件给子组件传值子组件中通过声明props来接收数据父组件通过相应属性给子组件传值子组件给父组件传值父组件监听自定义事件子组件使用$emit()触发自定义事件,抛出值(内联代码可以用$event拿到该值)不相关的组件传值使用自定义事件传值不相关的组件没有父子关系,所以需要一
2020-08-04 16:34:03 284
原创 webpack的tree-shaking
先来看tree-shaking的几种使用情况情况一// ./common/util.jsimport lodash from 'lodash-es';var func1 = function(v) { alert('111');}var func2 = function(v) { return v;};export { func1, func2}// ./index.jsimport { func2 } from '../common/util';var a
2020-08-03 21:05:22 511
原创 Vue源码解读
Vue的不同构建版本对于Vue的不同构建版本,以下图说明有min后缀的是生产版本,其他是开发版本Full表示完整版,同时包含编译器和运行时编译器:将模板字符串编译为JavaScript渲染函数的代码,即template => h(),体积大(3000多行),效率低运行时:用来创建Vue实例,渲染并处理虚拟DOM等代码,不包含编译器,体积小,效率高Runtime-only是运行时版本,不包含编译器UMD:通用模块化版本,支持多种模块方式,可以在浏览器环境下直接运行(挂载到wind
2020-07-31 14:43:29 409
原创 浏览器网络与安全
HTTP协议HTTP/0.9只有一个请求行,并没有 HTTP 请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求了。服务器也没有返回头信息,这是因为服务器端并不需要告诉客户端太多信息,只需要返回数据就可以了。返回的文件内容是以 ASCII 字符流来传输的,因为都是 HTML 格式的文件,所以使用 ASCII 字节码来传输是最合适的。HTTP/1.0支持多种类型的文件下载是 HTTP/1.0 的一个核心诉求增加了请求头和响应头来支持多种不同类型的数据首先,浏览器需要知道
2020-07-29 14:21:06 830
原创 浏览器页面的事件循环系统
概述由于浏览器页面的渲染进程的主线程要执行很多任务,如DOM构建、样式计算、布局计算、绘制、JavaScript执行、接收输入事件等,并且这些任务因为需要交互性来不断产生,无法事先安排,因此需要一个任务调度系统来统筹规划这些任务的执行。在浏览器中,统筹调度任务的系统就是事件循环系统(Event-Loop)事件与循环事件循环系统在于事件和循环这两个概念事件:接收外部的输入事件,产生任务循环:线程执行完任务后并不退出,而是循环等待输入事件产生的任务并执行其实这两个概念使用ES6的generator函
2020-07-27 15:28:13 373
原创 浏览器中的JavaScript执行机制
执行上下文变量提升在JavaScript代码执行时,JavaScript引擎把变量和函数的声明提升到代码开头的“行为”,提升后的变量会设置默认值undefined,函数声明是有值的。变量提升发生在JavaScript的编译阶段。JavaScript的执行流程JavaScript代码会经过编译后再执行编译阶段生成执行上下文生成可执行代码执行上下文之环境变量JavaScript执行一段代码时的运行环境,保存代码执行时的变量环境、词法环境、外部执行上下文outer和this。比如调用函
2020-07-26 12:43:32 553
原创 浏览器架构、渲染原理与页面优化
注:以下内容来自于极客时间李兵老师的《浏览器工作原理与实践》课程总结浏览器架构多进程架构概述现代浏览器采用多进程架构的模式,一般而言,一个页面会是一个渲染进程(可能存在同一站点same-site多页面复用同一个渲染进程的情况),另外,还有浏览器的主进程、GPU进程、网络进程、插件进程等等。如下图各个进程的功能主进程:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。渲染进程:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blin
2020-07-24 15:23:20 629 1
原创 Vue虚拟DOM原理与snabbdom
虚拟DOMJavaScript对象描述真实DOM真实DOM的属性很多,创建DOM节点开销很大虚拟DOM只是普通JavaScript对象,描述属性并不需要很多,创建开销很小手动操作DOM很难跟踪以前的DOM状态,而虚拟DOM可以跟踪上一次状态,维护程序的状态信息。虚拟DOM的作用维护视图与状态的关系复杂视图情况下,可以提升渲染性能还可以实现跨平台渲染,如SSR、原生应用、小程序等虚拟DOM开源库Snabbdomvirtual-domSnabbdom基本使用snabbdo
2020-07-21 23:05:15 336
原创 Vue响应式原理与模拟
Vue数据响应式原理:数据劫持(拦截)、观察者模式Vue2: getter和setterVue3: Proxy通信模式发布订阅模式事件中心,提供发布事件(emit方法)和订阅事件(on)的接口,是发布订阅模式的核心,作为事件和事件处理函数的仓库。订阅者:使用事件中心的订阅接口来订阅某种类型的事件,待事件发布时,会调用事件处理函数发布者:使用事件中心的发布接口来发布某种类型的事件,触发事件处理函数的调用观察者模式:Vue的响应式机制观察者(订阅者):watcher拥有一个up
2020-07-20 20:47:15 238
原创 Vue-Router核心原理实现
vue-router基本使用配置路由文件// 路由配置文件router/index.js// 导入vue和vue-routerimport Vue from 'vue'import VueRouter from 'vue-router'// 导入首页视图文件import Index from '../views/Index.vue'// 注册路由插件// Vue.use()用来注册插件,会调用传入对象的install方法Vue.use(VueRouter)// 定义路由规则,即
2020-07-17 21:50:50 535
原创 前端工程化之规范化
为什么要有规范标准开发需要多人协同开发者不同的编码喜好统一标准,降低维护成本哪里需要规范化标准代码、文档、日志开发过程中的人为成果代码标准化决定项目质量,最为重要如何实施规范化人为的标准约定通过工具实现LintESLint安装安装:npm install eslint -D,安装后就会在node_modules/.bin/下有一个CLI程序。使用先配置,再检查使用eslint --init生成配置文件,可以是JavaScript,也可以是JSON文件。使用npx
2020-07-14 20:22:45 567
原创 JavaScript打包之Rollup和Parcel
Rollup:打包ESM主要面向打包JavaScript类库。使用方法安装npm install rollup -D,同时在node_modules/.bin/目录下会安装有CLI程序。使用npx rollup <entry file> --format <module type> --file <output file>来对指定的入口文件进行打包,其中–format后面的<module type>指定打包后的模块遵循的模块规范(如iife – 立即
2020-07-14 11:00:39 368
原创 JavaScript打包之Webpack
打包:从开发到生产解决ES Module的浏览器兼容问题,编译ES6+到ES5解决模块请求频繁的问题,模块打包成一个文件资源都需要模块化,管理所有资源的依赖关系,便于业务代码与相关资源的统一维护打包工具作用:使用模块化为开发环境提供便利,使用打包为生产环境提供效率。Webpack:打包所有资源webpack的执行是node环境,因此相对路径必须要用./开头,不能省略。配置文件webpack会运行配置文件,拿到配置文件导出的配置对象,有多种导出配置对象的方式直接导出配置对象modul
2020-07-13 22:48:23 916
原创 JavaScript模块化概述
模块化演进阶段一:文件即模块,使用<script>标签引入污染全局作用域命名冲突无法管理模块依赖关系阶段二:命名空间方式,文件暴露一个全局对象,所有方法挂载到全局对象上形成命名空间缓解命名冲突,但无法避免没有私有属性,从而无法避免出现私有属性值被不小心更改的情况依赖关系仍然无法管理阶段三:IIFE立即执行函数表达式,可以给全局对象上挂载属性来暴露接口,也可以返回一个对象来暴露接口。私有成员得到保证通过IIFE传递参数,可以在一定意义上管理依赖关系。如;(fun
2020-07-10 15:57:31 189
原创 前端工程化之自动化构建
自动化构建源代码自动转换为生产环境代码NPM Scripts脚本实现自动化利用npm scripts脚本实现自动化,npm scripts原理参照阮一峰老师博客钩子机制实现构建流:pre-<name>:该命令在name命令之前先启动post-<name>:该命令在name命令之后才启动npm-run-all模块:同时并行执行多个脚本命令,如npm-p build serve同时启动build和serve脚本命令常用自动化构建工具gulp:基于虚拟文件对象
2020-07-07 11:55:50 465
原创 npm包安装与npm link
npm包安装的两种方式全局安装npm install <package-name> -g意义:将安装的包作为一个命令行工具,在任意目录下都可以访问调用安装路径:默认安装在 /usr/local/lib/node_modules下,可以通过配置安装到其他路径下。如通过nvm(node版本管理工具)可以配置到对应的node版本下面局部安装npm install <package-name>意义:在当前目录下,使用require语句加载安装路径:在当前目录下的node
2020-07-06 12:50:25 1647
原创 前端工程化之脚手架工具
脚手架工具常用脚手架工具React项目create-react-appVue项目vue-cliAngular项目angular-cliYeoman通用型脚手架工具Plop创建一个组件/模块所需要的文件(类似于Yeoman的sub-generator)Yeoman基本使用全局安装yeoman:npm install yo -g全局安装generator:安装项目对应的generator包,让yeoman运行generator包来创建项目基本结构。yeoman + generator包
2020-07-04 11:16:20 448
原创 JavaScript语言层面的优化
JavaScript优化内存管理高级语言自带垃圾回收机制如果不注意内存管理,可能会导致内存泄漏问题。内存管理:开发者主动申请空间、使用空间和释放空间。JavaScript中并未提供相应的API,由执行引擎根据语言来执行内存管理操作。申请空间let obj = {};使用空间obj.name = 'foo';释放空间obj = null;垃圾回收与常见GC算法垃圾回收程序执行时,会阻塞JavaScript的执行。两种对垃圾的判断:对象不再被引用时,称为垃圾对象不能从根上访问
2020-06-30 21:00:11 203
原创 JavaScript相关的类型注解系统
TypeScrip类型系统强类型与弱类型(类型安全方面)非权威机构的定义强类型函数的实参与形参的类型必须相同类型约束不允许隐式类型转换弱类型函数的实参与形参的类型在语法上不必相同类型上约束少允许任意的数据隐式类型转换JavaScript的TypeError是在运行时通过逻辑判断抛出的,而不是编译时就会抛出。静态类型与动态类型(类型检查方面)静态类型变量在声明时类型就是明确的,且声明后变量的类型不允许再修改通俗地说,静态表示的是看一眼就知道是什么动态类型变量在
2020-06-29 22:43:50 1564
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人