,网上有很多相关的文章和实现都非常完美,本文主要讲述的是用一种非常规的使用非递归方法实现深拷贝 本文的深拷贝只考虑数组、对象、简单值三种数据类型 要实现判断数据类型,先来实现这 3 个判断类型的工具方法...其实几乎所有的函数递归,都可以使用非递归的方法实现。...在迭代的过程中,我们每一级都是对这个引用的子部分进行处理 const copy = source => { // 简单值直接返回 if (!...类似于数组处理 对象键是对象 对象键是数组 对象键是简单值 再加上循环引用处理也非常简单,每次迭代的最后将当前source添加到set中。...虽然花了一些力气,实现这个拷贝,代码也比递归版本复杂很多,性能可能也更差,但是如果能重头看到尾,并且自己实现一遍,相信会大大加深自己对深拷贝的理解和函数递归思想的的理解。
,例如:原型继承、call继承、寄生组合继承、es6中的继承等,有些方式会存在一些问题,我项目中后来都是基于class中的extend实现继承的 谈一下你对作用域链和原型链的理解 作用域链 函数执行会形成一个私有的作用域...,而且作用域(栈)不销毁,这些私有变量存储的值也都保存下来了,所有整体来说闭包就是为了保护和保存变量的 实际项目开发中,很多地方使用到了闭包,例如: 1.循环事件绑定,由于事件绑定是异步编程的,我们此时在循环的时候把索引存储起来...1.改变函数中的THIS(并且让函数执行) 2.可以基于CALL让类数组借用数组原型上的方法(例如:借用SLICE实现把类数组转换为数组) 3.可以基于CALL实现继承 4.可以基于APPLY获取数组中的最大值和最小值...先找到的是所有的A,操作起来是消耗性能的,我们在使用CSS选择器的时候尽可能减少对标签选择器的使用 } 11.CSS雪碧图技术(css sprite / css 图片精灵) 把所有相对较小资源图片汇总到一张大图上...JS,而且CSS中的transform变形还开起了硬件加速 3.JS中尽量减少对EVAL的使用,因为JS合并压缩的时候,可能出现由于符号不完善,导致的代码执行优先级错乱问题,EVAL处理起来消耗的性能也是偏大一点的
问题:判断字符串A在中所有出现字符串B中(长度大于1)的索引。...不得使用字符串方法indexof,substring等 有小伙伴在面试遇到了这个问题,乍一看如果使用使用字符串方法indexof,substring,很简单容易实现,但如果不使用这些方法,怎么样才能实现这个需求呢...// 思路: 如果不能使用字符串的相应方法,我们可以把字符串转换成数组,使用递归函数不断去比对相应的数组索引,然后把满足条件的索引打印出来,其实很多现在前后端交互处理数据的方法,用的都是递归偏多,...举个从小就听过的例子:从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山... 其实递归,就是在运行的过程中调用自己。...程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。
2、非递归:另一种深度优先算法 非递归有很多形式,我仅使用一种最常用的来展示非递归在DOM树查找中的实现。...这种方式在Google浏览器查找元素中得到大量使用,不过Google首先使用m_map保存了所有元素id,然后通过map的方式实现查找,这个map 以id为做为key, 以element node 作为...class、tag,以及querySelector中通过单个Id和class查找中同样使用了非递归。...哈希的思路很简单,如果所有的键都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。...由于Javascriot Object数据类型就是基于 Hashtable实现的,所以,当使用使用对象的键查找值时,浏览器引擎已经在底层通过哈希函数将每个键转化为数据的索引,并使用内建的哈希碰撞处理函数处理了碰撞冲突
递归与迭代都涉及重复:迭代显式使用重复结构,而递归通过重复函数调用实现重复。 递归与迭代都涉及终止测试:迭代在循环条件失败时终止,递归在遇到基本情况时终止。...对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用...(这一切都是基于某类只需要存在一个实例对象的前提来讨论) 首先静态变量方式不能确保某类的实例的唯一性,这样在项目中,可能因为在某个文档类中对该静态变量进行再次赋值,存不可意料的风险(这种风险可以规避...这并不是因为HashTable有什么特殊的实现层面的原因导致不能支持null键和null值,这仅仅是因为HashMap在实现时对null做了特殊处理,将null的hashCode值定为了0,从而将其存放在哈希表的第...,标记所有从这些对象可达的存活对象;由于在标记期间应用可能正在运行并更新引用,所以到并发标记阶段结束时,未必所有存活的对象都能确保被标记;所以必须再次停顿,称为重新标记;最后一个阶段是并发清除。
/src/index.js"); }) 图片 webpack详细工作流程 图片 map和weakMap的区别 (1)Map map本质上就是键值对的集合,但是普通的Object中的键值对中的键只能是字符串...has(key):该方法返回一个布尔值,表示某个键是否在当前Map对象中。 delete(key):该方法删除某个键,返回true,如果删除失败,返回false。...其键必须是对象,原始数据类型不能作为key值,而值可以是任意的。...它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。 WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。...在之前的调度算法中,React 需要实例化每个类组件,生成一颗组件树,使用 同步递归 的方式进行遍历渲染,而这个过程最大的问题就是无法 暂停和恢复。
可以通过上述的高级知识点来完成,在特定的场景下,比如在 IO 中,不需要列出所有的可能性,只需要通过一个抽象过程来完成所有情况的处理,并保证不会抛出异常。...所有的数据都应以参数的形式提供给函数,而 this 不遵守这种规则。 二、为什么JS函数内部可以使用for循环吗? 很多人可能没有想过这个问题 其实在纯函数式语言中,是不存在循环语句的。...循环语句需要使用递归实现,但是 JS 的递归性能并不好,比如没有尾递归优化,那怎么办呢? 为了能支持函数式编程,又要避免 JS 的递归性能问题。...第二张图,使用了尾递归,最后一个表达式就是递归函数本身。 问题来了,为什么说 JS 对尾递归支持的不好呢?...如果浏览器的解释环境对 JS 的尾递归优化的不好,那就说明,JS 的尾递归优化很差。由于浏览器有很多,可见 JS 要实现全面的尾递归优化,还有很长的路要走。
通常对程序员来说,栈是不可见的,几乎在每个现代的编程语言中,栈都是支持线程执行的内存区域。 堆是许多现代编程语言实现中的另一重要内存区域,用于动态内存的分配和释放,例如创建列表和对象。...对象的域——我们与对象中数据的关系 悠然一曲泉明调 浅立闲愁轻闭门 对象的域一般是指键与简单值的映射,对象中的一些方法成为了键与值之间的函数映射,构造函数是最先被调用的方法。...在设计模式中,适配器模式的目的与抽象对象是一致的,隔离了应用程序与具体的功能实现。抽象对象在大型系统设计中举足轻重,抽象对象的实现根据涉及的具体编程语言而定。...所有现代高级编程语言都有一个类型系统,在开发和执行过程中的不同节点检测数据类型。静态类型的语言如Java 和 Haskell,动态类型如JS,python等等。...关于参数,没有输入参数和返回值就是纯过程函数, 而同时有参数和返回值才可能实现幂等性。多参数的我可以柯里化为单参数高阶函数,而参数中是函数的话可以形成处理管道,或者回调函数。
关联对象,放回一个Boolean值 delete(key) 移除key的关联对象,之后执行has(key)方法返回false 和Map有什么区别?...在JS里的Map API共用两个数组(key、value),设置的key、value都会加到这两个数组的末尾,并对key产生引用。...当从map取值时,需要遍历所有的key,然后通过索引从value数组中取出相应index的值。...,并且其中的每个对象只能出现一次,在WeakSet集合中是唯一的 方法 add(value) 在该WeakSet对象中添加一个新的元素value delete(value) 在该WeakSet对象中删除...has(value) 返回一个Boolean值,表示给定的value值是否存在这个WeakSet中 和Set有什么区别 Set的value可以是任何值,WeakSet的值只能是对象 const name
Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。 3.Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。...5.Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。...动态卸载和加载CSS style-loader为 css 对象提供了use()和unuse()两种方法可以用来加载和卸载css 比如实现一个点击切换颜色的需求,修改index.js ?...处理引用的第三方库,暴露全局变量 webpack.ProvidePlugin参数是键值对形式,键就是我们项目中使用的变量名,值就是键所指向的库 ?...9. code splitting、懒加载(按需加载) 说白了就是在需要的时候在进行加载,比如一个场景,点击按钮才加载某个js. ? 10. JS Tree Shaking ? 11. 图片处理 ?
Omit 实现 Omit,作用恰好与 Pick 相反,排除对象 T 中的 K key: interface Todo { title: string description...> // expected to be '1' | '2' | '3' 该题将元组类型转换为其所有值的可能集合,也就是我们希望用所有下标访问这个数组,在 TS 里用 [number] 作为下标即可:...Chainable 类型,拥有该类型的对象可以 .option(key, value) 一直链式调用下去,直到使用 get() 后拿到聚合了所有 option 的对象。...如果我们用 JS 实现该函数,肯定需要在当前闭包存储 Object 的值,然后提供 get 直接返回,或 option 递归并传入新的值。...这里有个看似不值得一提,但确实容易坑人的地方,就是如何描述一个对象仅包含一个 Key 值,这个值为泛型 K 呢?
「ECMAScript 只是对实现ECMA-262规范的一门语言的称呼」 JS 实现了ECMAScript Adobe ActionScript 也实现ECMAScript 文档对象模型(DOM) DOM...---- undefined vs null 在JS中,存在两个「空值」 undefined null 从使用上对其进行分类 undefined: 是「语言层面」上使用的非值(定义一个变量,但未赋值,此时该变量会被...「作用域和执行上下文的关系」 ❝ 「作用域」只是执行上下文有权访问的一组「有限」的变量/对象 同一个执行上下文上可能存在多个作用域 ❞ ---- 作用域链 在 JS 执行过程中,其「作用域链是由词法作用域决定的...---- 闭包 函数即对象 「在JS中,一切皆对象」。那从语言的设计层面来讲,「函数是一种特殊的对象」。 函数和对象一样可以拥有属性和值。...使用尾递归,即「一个函数中所有递归形式的调用都出现在函数的末尾」,对于尾递归来说,由于只存在一个调用记录,所以永远不会发生"栈溢出"错误。
runtime,由于其渲染出来的 DOM 对象实际上是一个 JS 对象,故而可以运行在所有的 JS 环境中。...组合式 API 与 选项式 API的区别简单表面的理解就是 script 部分代码编写风格的区别。 在 Vue 2 中,如果我们需要写一个 tag 选择的组件,我们的写法可能如下: ?...在 Vue 2 中,Vue 会生成一个虚拟 DOM 树,我们每次修改之后,又会生成一个新的虚拟 DOM 树,Vue 通过递归遍历的方式,对这两个虚拟 DOM 树上的每一个节点的属性进行对比,判断是否需要更新...操作进行设置;如果是对象类型的数据,且非只读,则会递归调用 reactive 方法去创建响应式的副本,相较于 Vue 2 在应用初始化时就递归劫持所有的 get 方法而言,这种处理方式有着很明显的优化。...trigger 方法是在修改值时,通过 target 对象,从全局 weak map 对象中取出对应的depMap 对象,然后再根据修改的 key 取出对应的 dep 依赖集合,并遍历并执行该集合中所有的
实际在函数式编程语言实现中,Maybe确实只是一个类型(称为代数类型),具体的一个值有具体类型Just或Nothing,就像数字可以分为有理数和无理数一样。...其他的编程语言特性,在函数式编程中也能找到对应的影子,比如循环结构,我们往往使用函数递归来实现。 3.5 IO的处理方式 终于到IO了,如果不能处理好IO,我们的程序是不健全的。...举个例子,面向对象里面的继承,我在函数式编程中可以使用组合compose或者高阶函数hoc来实现。 尽管在实现上是等价的,但和面向对象的编程范式对比,函数式编程有很多优点值得大家去尝试。...A:业务拆分的时候,函数式的思维是单向的,我们会通过实现,想到它对应需要的基础组件,并递归地思考下去,功能实现从最小粒度开始,上层逐步通过函数组合来实现。...相比于面向对象,这种方式在组合上更方便简洁,更容易把复杂度降低,比如面向对象中可能对象之间的相互引用和调用是没有限制的,这种模式带来的是思考逻辑的时候思维会发散。
Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。 Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。...Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。...动态卸载和加载CSS style-loader为 css 对象提供了use()和unuse()两种方法可以用来加载和卸载css 比如实现一个点击切换颜色的需求,修改index.js ?...处理引用的第三方库,暴露全局变量 webpack.ProvidePlugin 参数是键值对形式,键就是我们项目中使用的变量名,值就是键所指向的库 ?...9. code splitting、懒加载(按需加载) 说白了就是在需要的时候在进行加载,比如一个场景,点击按钮才加载某个js. ? 10. JS Tree Shaking ? 11. 图片处理 ?
为什么使用懒加载 懒加载的原理 为什么使用预加载 实现预加载的方法 预加载的应用场景 JS垃圾回收机制说一下 如果页面卡顿,你觉得可能是什么原因造成的?有什么办法锁定原因并解决吗?...判断当前值是否为对象 1、如果不是对象,直接返回 2、如果是对象,创建结果数组,遍历对象,对当前值进行递归拷贝。...Map 的键可以为任意值,而 WeakMap 的键只能是弱引用对象,在进行垃圾回收的时候不会考虑 WeakMap 对对象的引用。...使用的组件不需要特殊处理。 具体还能结合业务进行考量。 JS 的 sort() 是怎么实现的 是使用插入和快排实现的。在某个长度内使用插入,在大于某个长度时使用快排。...如何获取嵌套对象所有的Keys 1、递归获取:如果Key对应的value是对象,继续递归获取,直到不是对象。
当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项// 复用代码:它是一个配置对象,选项和组件里面一样const mymixin = { methods: { dosomething...中引入的composition api,可以很好解决这些问题,利用独立出来的响应式模块可以很方便的编写独立逻辑并提供响应式的数据,然后在setup选项中组合使用,增强代码的可读性和维护性。...pinia显然在这方面有了很大改进,是时候切换过去了对Vue SSR的理解Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。...相比于其他模板引擎(ejs, jade 等),最终要实现的目的是一样的,性能上可能要差点怎样理解 Vue 的单向数据流数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件对原始数据进行修改...值来作路由,支持所有浏览器history : 依赖 HTML5 History API 和服务器配置abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。
实际在函数式编程语言实现中,Maybe确实只是一个类型(称为代数类型),具体的一个值有具体类型Just或Nothing,就像数字可以分为有理数和无理数一样。...其他的编程语言特性,在函数式编程中也能找到对应的影子,比如循环结构,我们往往使用函数递归来实现。 IO的处理方式 终于到IO了,如果不能处理好IO,我们的程序是不健全的。...举个例子,面向对象里面的继承,我在函数式编程中可以使用组合compose或者高阶函数hoc来实现。 尽管在实现上是等价的,但和面向对象的编程范式对比,函数式编程有很多优点值得大家去尝试。...A:业务拆分的时候,函数式的思维是单向的,我们会通过实现,想到它对应需要的基础组件,并递归地思考下去,功能实现从最小粒度开始,上层逐步通过函数组合来实现。...相比于面向对象,这种方式在组合上更方便简洁,更容易把复杂度降低,比如面向对象中可能对象之间的相互引用和调用是没有限制的,这种模式带来的是思考逻辑的时候思维会发散。
生成器可以按需逐个生成值,而不是一次性生成所有值,从而节省内存。 生成器可以通过两种方式创建: 使用生成器函数:生成器函数是一种普通的函数,使用yield语句来生成值。...分治算法:分治算法通常使用递归函数将问题分解为更小的子问题,并将结果合并。 Python中的迭代器和可迭代对象有什么区别? 答案:迭代器和可迭代对象是Python中处理迭代的两个相关概念。...通过加一层适配器,对现有接口进行增强,用户在使用适配器时无需知道适配器内部的工作细节, 所以适配器类内部可以直接组合现有接口(也就是适配者), 适配者的在适配器中的调用对于用户是无感的,用户只需要关心适配器即可...(即装饰和不装饰),所以用户对原类文件的存在是有感知的,使用聚合的方式传入要装饰的原类对象。...为避免混淆,应尽量使用术语“pickling”和“unpickling”。 字典和JSON有什么区别? Dict是Python的一种数据类型,是经过索引但无序的键和值的集合。
在我们函数中最主要的功能当然是根据输入返回结果,而在函数中我们最常见的副作用就是随意操纵外部变量。由于 JS 中对象传递的是引用地址,哪怕我们用 const 关键词声明对象,它依旧是可以变的。...相信你已经在很多地方接触过这个词,在 Redux 的三大原则中,我们看到,它要求所有的修改必须使用纯函数。...资源占用:在 JS 中为了实现对象状态的不可变,往往会创建新的对象,因此,它对垃圾回收(Garbage Collection)所产生的压力远远超过其他编程方式。这在某些场合会产生十分严重的问题。...递归陷阱:在函数式编程中,为了实现迭代,通常会采用递归操作,为了减少递归的性能开销,我们往往会把递归写成尾递归形式,以便让解析器进行优化。...但是众所周知,JS 是不支持尾递归优化的(虽然 ES6 中将尾递归优化作为了一个规范,但是真正实现的少之又少) …… 因此,在性能要求很严格的场合,函数式编程其实并不是太合适的选择。
领取专属 10元无门槛券
手把手带您无忧上云