- 博客(33)
- 收藏
- 关注
原创 初识渲染器
相信大家都很明确上述虚拟 DOM 要处理怎样的事情,首先我们可以看到他是一个树形结构的 JavaScript 对象,我们需要有一个渲染函数,他接受的参数就是上述类型的 JavaScript 对象,然后将其转换成一个真实的 DOM,放置在页面上,渲染器是非常重要的一个角色,我们所使用的 Vue.js 组件都是要依赖渲染器来工作,这是一个非常重要的工作环节,这里我们初步了解一下渲染器的工作原理。我们已经知道什么是虚拟 DOM 了,那么,虚拟 DOM 该如何变成真实的 DOM 呢?最后我们执行渲染函数。
2023-11-02 11:50:47
87
原创 声明式的描述UI
由上述可得,在Vue.js中,哪怕是事件,都有之对应的描述方式,用户不需要写任何命令式的代码,这就是所谓的声明式的UI。首先我们要知道Vue.js3是一个声明式的UI框架,意思是说用户在使用Vue.js3开发页面时是声明式的描述UI的。那么我们来思考一下,如果让你设计一个声明式的UI框架,你会怎么设计呢?我们了解一下编写前端页面都要涉及哪些内容,如下。声明式的形式应该如何描述上面的内容呢?这就是框架设计需要思考的地方,vue3是这样解决的。
2023-11-02 10:18:11
111
原创 Tree-Shaking (副作用)
接着上个帖子提出的疑问,我们深入研究一下为什么没有剔除foo函数。其实这里涉及到了Tree-Shaking中的第二个关键点—副作用。顾名思义,即一个函数的调用,可能对其他地方造成修改,那么在打包的过程中我们就不能将其剔除。这个时候又要有人说,这个foo函数仅仅时对对象的值进行了获取obj.foo,没有其他的修改。我们再一步深入,如果这个obj对象是一个通过Proxy代理的对象,读取它的属性就会触发该属性的get夹子,那在get夹子中会不会有造成其他变量的改变呢?
2023-10-24 15:36:36
142
原创 Tree-Shaking (自动剔除`dead-code`)
我们有一个demo工程文件内容分别是:上面是一个很直观且简单的例子,utils.js文件中导出了两个函数,分别是foo与bar,然后在input.js中导入了foo函数并执行。但是我们并没有导入bar函数。下面我们使用 rollup.js 进行构建:使用input.js作为入口,打包出来的文件为bundle.js我们不难发现,在最终生成的bundle.js中,我们没有发现utils.js中导出的bar函数,这是为什么呢?就是因为这块代码在至始至终都没有被使用到,所以它被当成被删除了。
2023-10-24 15:11:46
56
原创 框架的选择(运行时&编译时)
纯运行时框架:由于它没有编译的过程,因此我们没办法分析用户提供的内容。运行时+编译时:可以分析用户提供的内容,看看哪些内容未来可能会改变,哪些内容永远不会改变,这样我们就可以在编译的时候提取这些信息,然后将其传递给 Render 函数,Render 函数得到这些信息之后,就可以做进一步的优化纯编译时:也可以分析用户提供的内容。由于不需要任何运行时,而是直接编译成可执行的 JavaScript 代码,因此性能可能会更好,但是这种做法有损灵活性,即用户提供的内容必须编译后才能用##拓展纯编译时。
2023-10-23 20:49:50
108
原创 虚拟DOM的性能
到这里可能你还会有人讲,innerHTML的性能还是有可能优于虚拟DOM,那么,如果页面的元素数量级很高,如果还采取DOM销毁与创建,性能定然没有虚拟DOM好!使用innerHTML更新页面的的过程是**重新构建HTML字符串,再重新设置DOM元素的innerHTML属性,**那么这样将来,即使是我仅仅更新了一个元素中的一个文字,就等价于。这里我们从宏观的角度只看数量级上的差异。为了渲染出一个页面,首先要把字符串解析成了DOM树,这是一个涉及DOM的计算,因此,它的性能消耗远比Javascript大的多。
2023-10-23 19:40:12
43
原创 leetode: 70.爬楼梯(最简单那的DP)
动态规划(Dynamic Programming)是一种用于解决一类具有重叠子问题和最优子结构性质的问题的算法思想。它通过将一个问题分解成较小的子问题,并使用递归或迭代的方式求解这些子问题,最终得到原问题的解。动态规划通常用于优化问题,其中目标是找到一个最优解,使某个特定的目标函数最大或最小化。动态规划的核心思想是将大问题分解成小问题,并将小问题的解存储起来,以避免重复计算。这种存储和复用子问题解的方法称为“记忆化”或“缓存”,可以通过表格、数组或哈希表来实现。
2023-08-19 14:47:29
60
原创 leetcode:28. 找出字符串中第一个匹配项的下标
外部创建一个for循环,当匹配到字母与目标字符串首位相同时,进入内部while循环进行逐个比对,发现不相同的字母是执行break,跳出while循环,继续执行for循环;如果内部while循环依次匹配到了所有目标字符,那么就直接return当前i,这就是第一个匹配的下标。
2023-08-16 20:10:19
78
原创 leetcode:20.有效的括号
题解:1.首先我们创建arrMap来存储括号字符串,括号的左侧部分为key,右侧部分为value,如下2.接下来进行初步判断,如果字符串为空,那么直接返回3.创建stack数组来存储下面循环逻辑要存储的括号字符串4.开始循环字符串,本题的核心逻辑在此部分创建循环语句,遍历字符串,用ch来存储当前字符每次循环都判断当前字符ch是否为或case1:如果是,则根据上面创建的mapArr来将它的另一半括号mapArr[ch]推入stackcase2:如果不是,则需要判断当前stack。
2023-08-11 21:19:31
58
1
原创 46:全排列:深度优先搜索
它的基本思想是从起始节点开始,沿着一条路径不断深入地遍历,直到达到某个叶节点或无法继续深入为止,然后回溯到上一级节点,再继续探索其他路径。这种深入优先的搜索方式使得算法能够尽可能深入地探索一个分支,直到无法再深入为止,然后回溯到上一级节点,继续搜索其他分支。然而,由于深度优先搜索会深入探索一个分支,可能会导致遍历的路径较长,因此在某些情况下可能会造成效率较低,或者需要使用剪枝等方法进行优化。需要注意的是,深度优先搜索不一定能找到最优解,因为它可能会在一个分支中不断深入,而忽略了其他可能的解。
2023-08-09 21:11:33
387
1
原创 leetcode:17. 电话号码的字母组合(dfs)
Problem: 17. 电话号码的字母组合文章目录思路Code思路看到排列组合相关的问题,首先想到的就是回溯算法求解,也就是深度优先搜索(dfs)进行求解,具体的编码解释已经在代码注释中标出,请看下面的code:Code/** * @param {string} digits * @return {string[]} */var letterCombinations = function(digits) { if(!digits.length){ return
2023-08-08 21:47:27
46
原创 leetcode:15. 三数之和(双指针解法)
初步看,无法看到如何使用双指针解题(刚上手的时候也想到了这个,尝试套用),由于双指针通常操作的是有序数组,因此,先使用了sort()排序,将数组变为有序的。以上便是while循环中主要执行的逻辑,但是不要急,到此还没有结束,别忘了题目上还有说明不要出现重复值,还要进行如下判断。总结:第一次上手这道题的时候,真的是无从下手,只能想到暴力枚举,导致时间复杂度很大。(这里的’*'直接理解为指向数组的值,相当于解引用吧,下面都是),接下来比较。1.在外层for循环中,如果当前值和前一个值相等,则直接跳过。
2023-08-07 21:19:21
91
1
原创 5.最长回文子串(leetcode题解):中心扩展法+符串空隙插值
中心扩展法是一种用于寻找回文串的算法。它通过遍历字符串中的每一个字符或字符间的空隙,以每个字符或字符间的间隔为中心,向两边扩展,判断是否为回文串。中心扩展法的时间复杂度为 O(n^2),其中 n 是字符串的长度。遍历字符串的每个字符或字符间的空隙,以每个字符或字符间的间隔为中心,向两边扩展。对于每个中心,分别向左和向右扩展,直到遇到不满足回文条件的字符。回文条件是左右两边的字符相同。在每个中心扩展的过程中,记录下最长的回文串。最终得到的最长回文串就是字符串中的最长回文子串。
2023-08-01 22:38:39
36
1
原创 Vue组件data为什么必须是个函数而Vue的根实例则没有此限制?
Vue组件可能存在多个实例,如果使用对象形式定义data,则会导致它们共用一个data对象,那么状态变更将会影响所有组件实例,这是不合理的;米用函数形式E义,在Ehl不E在该嗯制,也是因为根实例只能有一个,不需要规避多实例之间状态污染问题。而在Vue根实例创建过程中则不存在担心这种情况。...
2022-02-11 17:34:19
423
原创 vue2.x中diff算法的总结
1. diff算法是虚拟DOM技术的必然产物:通过新旧虚拟DOM作对比(即diff),将变化的地方更新在真实DOM上;另外,也需要diff高效的执行对比过程,从而降低时间复杂度为O(n)。2.vue 2.x中为了降低Watcher粒度,每个组件只有一个Watcher与之对应,只有引入diff才能精确找到发生变化的地方。3.vue中diff执行的时刻是组件实例执行其更新函数时,它会比对上一次渲染结果oldVnode和新的渲染结果newVnode,此过程称为patch。4.diff过程整体遵循深度优先、.
2022-02-11 17:01:51
782
原创 JS时间戳转换为日期格式
JS时间戳转换为日期格式/*** 时间戳转换成指定格式日期** eg. ** dateFormat(11111111111111, 'Y年m月d日 H时i分')** → "2322年02月06日 03时45分"*/var dateFormat = function (timestamp, formats) { // formats格式包括 // 1. Y-m-d // 2. Y-m-d H:i:s // 3. Y年m月d日 // 4. Y年m月d日 H时
2021-03-09 19:56:01
585
原创 事件冒泡
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Do
2021-02-05 14:33:26
333
2
原创 复选框的功能实现
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script> window.onload =
2021-02-05 11:16:20
543
原创 封装一个简单的数组去重函数
数组去重的小函数//封装一个去重的函数 function unRepeat (arr) { var newArr = []; for (var i=0; i<arr.length; i++) { if(newArr.indexOf(arr[i]) == -1){ newArr.push(arr[i]); }
2021-01-31 17:30:10
1256
原创 对象与原型之间的关系
对象与原型之间的关系每一个基本的对象都会有自己的一个原型,当在使用每一个实例对象的时候,你所用到的属性或者方法,他都会现在自己的个体中寻找,如果找不到,则会去寻找他所对应得原型对象中所对应的属性或者方法,如果还找不到,会在向上查询一个环节,直至到object为空(null),如下图作为对象个体的mc来说,在使用hasOwnproperty()的方法时,我们并没有给mc对象这个方法,我们可以对mc所处的对象原型的对象进行查找,发现依然没有,再次向上寻找,才发现次方法。这里也说明了,所有自定义对象的对
2021-01-31 14:40:14
246
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人