题目描述:手写防抖节流
实现代码如下:
题目描述:实现一个方法使多维数组变成一维数组
最常见的递归版本如下:
扩展思考:能用迭代的思路去实现吗?
实现代码如下:
左边可以是任意值,右边只能是函数
这个问题相信很多人会第一时间想到 Promise.all
,但是这个函数有一个局限在于如果失败一次就返回了,直接这样实现会有点问题,需要变通下。以下是两种实现思路
触发高频事件 N 秒后只会执行一次,如果 N 秒内事件再次触发,则会重新计时。
简单版:函数内部支持使用 this 和 event 对象;
使用:
最终版:除了支持 this 和 event 外,还支持以下功能:
使用:
参考 前端进阶面试题详细解答
浮动的定义: 非IE浏览器下,容器不设高度且子元素浮动时,容器高度不能被内容撑开。 此时,内容会溢出到容器外面而影响布局。这种现象被称为浮动(溢出)。
浮动的工作原理:
浮动元素可以左右移动,直到遇到另一个浮动元素或者遇到它外边缘的包含框。浮动框不属于文档流中的普通流,当元素浮动之后,不会影响块级元素的布局,只会影响内联元素布局。此时文档流中的普通流就会表现得该浮动框不存在一样的布局模式。当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”。
浮动元素引起的问题?
清除浮动的方式如下:
height
属性clear:both
样式overflow:hidden
或者overflow:auto
题目描述:给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1
实现代码如下:
call
使用一个指定的 this 值和一个或多个参数来调用一个函数。
实现要点:
apply
apply 和 call 一样,唯一的区别就是 call 是传入不固定个数的参数,而 apply 是传入一个数组。
实现要点:
bind
bind 方法会创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
实现要点:
实现 new 关键字
new 运算符用来创建用户自定义的对象类型的实例或者具有构造函数的内置对象的实例。
实现要点:
使用:
实现 instanceof 关键字
instanceof 就是判断构造函数的 prototype 属性是否出现在实例的原型链上。
上面的 left.proto 这种写法可以换成 Object.getPrototypeOf(left)。
实现 Object.create
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的proto。
实现 Object.assign
实现 JSON.stringify
JSON.stringify([, replacer , space) 方法是将一个 JavaScript 值(对象或者数组)转换为一个 JSON 字符串。此处模拟实现,不考虑可选的第二个参数 replacer 和第三个参数 space
实现 JSON.parse
介绍 2 种方法实现:
eval 实现
第一种方式最简单,也最直观,就是直接调用 eval,代码如下:
但是直接调用 eval 会存在安全问题,如果数据中可能不是 json 数据,而是可执行的 JavaScript 代码,那很可能会造成 XSS 攻击。因此,在调用 eval 之前,需要对数据进行校验。
new Function 实现
Function 与 eval 有相同的字符串参数特性。
实现 Promise
实现 Promise 需要完全读懂 Promise A+ 规范,不过从总体的实现上看,有如下几个点需要考虑到:
Promise 写完之后可以通过 promises-aplus-tests 这个包对我们写的代码进行测试,看是否符合 A+ 规范。不过测试前还得加一段代码:
全局安装:
终端下执行验证命令:
上面写的代码可以顺利通过全部 872 个测试用例。
Promise.resolve
Promsie.resolve(value) 可以将任何值转成值为 value 状态是 fulfilled 的 Promise,但如果传入的值本身是 Promise 则会原样返回它。
Promise.reject
和 Promise.resolve() 类似,Promise.reject() 会实例化一个 rejected 状态的 Promise。但与 Promise.resolve() 不同的是,如果给 Promise.reject() 传递一个 Promise 对象,则这个对象会成为新 Promise 的值。
Promise.all
Promise.all 的规则是这样的:
Promise.race
Promise.race 会返回一个由所有可迭代实例中第一个 fulfilled 或 rejected 的实例包装后的新实例。
Promise.allSettled
Promise.allSettled 的规则是这样:
Promise.any
Promise.any 的规则是这样:
描述:将如下 JSON格式的虚拟DOM结构转换成真实DOM结构。
实现:
描述:实现一个发布订阅模式,拥有 on, emit, once, off
方法
渐进式网络应用(PWA)
是谷歌在2015年底提出的概念。基本上算是web应用程序,但在外观和感觉上与原生app
类似。支持PWA
的网站可以提供脱机工作、推送通知和设备硬件访问等功能。
Service Worker
是浏览器在后台独立于网页运行的脚本,它打开了通向不需要网页或用户交互的功能的大门。 现在,它们已包括如推送通知和后台同步等功能。 将来,Service Worker
将会支持如定期同步或地理围栏等其他功能。 本教程讨论的核心功能是拦截和处理网络请求,包括通过程序来管理缓存中的响应。
fn.length
为0)众所周知 JS 是门非阻塞单线程语言,因为在最初 JS 就是为了和浏览器交互而诞生的。如果 JS 是门多线程的语言话,我们在多个线程中处理 DOM 就可能会发生问题(一个线程中新加节点,另一个线程中删除节点),当然可以引入读写锁解决这个问题。
JS 在执行的过程中会产生执行环境,这些执行环境会被顺序的加入到执行栈中。如果遇到异步的代码,会被挂起并加入到 Task(有多种 task) 队列中。一旦执行栈为空,Event Loop 就会从 Task 队列中拿出需要执行的代码并放入执行栈中执行,所以本质上来说 JS 中的异步还是同步行为。
以上代码虽然 setTimeout
延时为 0,其实还是异步。这是因为 HTML5 标准规定这个函数第二个参数不得小于 4 毫秒,不足会自动增加。所以 setTimeout
还是会在 script end
之后打印。
不同的任务源会被分配到不同的 Task 队列中,任务源可以分为 微任务(microtask) 和 宏任务(macrotask)。在 ES6 规范中,microtask 称为 jobs
,macrotask 称为 task
。
以上代码虽然 setTimeout
写在 Promise
之前,但是因为 Promise
属于微任务而 setTimeout
属于宏任务,所以会有以上的打印。
微任务包括 process.nextTick
,promise
,Object.observe
,MutationObserver
宏任务包括 script
, setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
很多人有个误区,认为微任务快于宏任务,其实是错误的。因为宏任务中包括了 script
,浏览器会先执行一个宏任务,接下来有异步代码的话就先执行微任务。
所以正确的一次 Event loop 顺序是这样的
通过上述的 Event loop 顺序可知,如果宏任务中的异步代码有大量的计算并且需要操作 DOM 的话,为了更快的 界面响应,我们可以把操作 DOM 放入微任务中。
Node 中的 Event loop 和浏览器中的不相同。
Node 的 Event loop 分为6个阶段,它们会按照顺序反复运行
timers 阶段会执行 setTimeout
和 setInterval
一个 timer
指定的时间并不是准确时间,而是在达到这个时间后尽快执行回调,可能会因为系统正在执行别的事务而延迟。
下限的时间有一个范围:[1, 2147483647]
,如果设定的时间不在这个范围,将被设置为1。
I/O 阶段会执行除了 close 事件,定时器和 setImmediate
的回调
idle, prepare 阶段内部实现
poll 阶段很重要,这一阶段中,系统会做两件事情
并且当 poll 中没有定时器的情况下,会发现以下两件事情
setImmediate
需要执行,poll 阶段会停止并且进入到 check 阶段执行 setImmediate
setImmediate
需要执行,会等待回调被加入到队列中并立即执行回调如果有别的定时器需要被执行,会回到 timer 阶段执行回调。
check 阶段执行 setImmediate
close callbacks 阶段执行 close 事件
并且在 Node 中,有些情况下的定时器执行顺序是随机的
当然在这种情况下,执行顺序是相同的
上面介绍的都是 macrotask 的执行情况,microtask 会在以上每个阶段完成后立即执行。
Node 中的 process.nextTick
会先于其他 microtask 执行。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。