前端成长进阶指北(JS篇)
点击上方 三分钟学前端,关注公众号
回复交流,加入前端编程面试算法每日一题群
嗨!各位早上好,三分钟学前端来一波第一季度回顾与总结,今天主讲 JS 篇 ,且已整理成了 pdf ,文末免费获取
下面进入正文吧👇
indexOf 和 findIndex 的区别
indexOf
:查找值作为第一个参数,采用===
比较,更多的是用于查找基本类型,如果是对象类型,则是判断是否是同一个对象的引用findIndex
:比较函数作为第一个参数,多用于非基本类型(例如对象)的数组索引查找,或查找条件很复杂
闭包 JS基础 编程题 (字节)
var foo = function(...args) {
// 要求实现函数体
}
var f1 = foo(1,2,3);
f1.getValue(); // 6 输出是参数的和
var f2 = foo(1)(2,3);
f2.getValue(); // 6
var f3 = foo(1)(2)(3)(4);
f3.getValue(); // 10
解答@Ishmael-Yoko
function foo(...args) {
const target = (...arg1s) => foo(...[...args, ...arg1s])
target.getValue = () => args.reduce((p, n) => p+ n, 0)
return target
}
闭包的使用场景,使用闭包需要注意什么
了解词法环境吗?它和闭包有什么联系?
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)
也就是说,闭包是由 函数 以及声明该函数的 词法环境 组合而成的
从页面 A 打开一个新页面 B,B 页面关闭(包括意外崩溃),如何通知 A 页面?
本题是 html 页面通信题,可以拆分成:
A 页面打开 B 页面,A、B 页面通信方式? B 页面正常关闭,如何通知 A 页面? B 页面意外崩溃,又该如何通知 A 页面?
从页面 A 打开一个新页面 B,B 页面关闭(包括意外崩溃),如何通知 A 页面?
监听一个变量的变化,需要怎么做
监听一个变量的变化,当变量变化时执行某些操作,这类似现在流行的前端框架(例如 React、Vue等)中的数据绑定功能,在数据更新时自动更新 DOM 渲染,那么如何实现数据绑定喃?
本文给出两种思路:
ES5 的 Object.defineProperty ES6 的 Proxy Proxy 相比于 defineProperty 的优势:
基于 Proxy
和Reflect
,可以原生监听数组,可以监听对象属性的添加和删除不需要深度遍历监听:判断当前 Reflect.get
的返回值是否为Object
,如果是则再通过reactive
方法做代理, 这样就实现了深度观测只在 getter
时才对对象的下一层进行劫持(优化了性能)所以,建议使用
Proxy
监测变量变化
讲下 V8 sort 的大概思路,并手写一个 sort 的实现
关于
Array.prototype.sort()
,ES 规范并没有指定具体的算法,在 V8 引擎中, 7.0 版本之前 ,数组长度小于10时,Array.prototype.sort()
使用的是插入排序,否则用快速排序。在 V8 引擎 7.0 版本之后 就舍弃了快速排序,因为它不是稳定的排序算法,在最坏情况下,时间复杂度会降级到 O(n2)。
于是采用了一种混合排序的算法:TimSort 。
讲下 V8 sort 的大概思路,并手写一个 sort 的实现
了解继承吗?该如何实现继承?
JS 继承主要由六种实现方式:
原型链继承 构造函数继承 组合继承 寄生组合继承 原型式继承 ES6 继承
什么变量保存在堆/栈中?
JS 就是动态语言,因为在声明变量之前并不需要确认其数据类型,所以 JS 的变量是没有数据类型的,值才有数据类型,变量可以随时持有任何类型的数据。
JS 值有 8 种数据类型,它们可以分为两大类——基本类型和引用类型。其中,基本类型的数据是存放在栈中,引用类型的数据是存放在堆中的。堆中的数据是通过引用和变量关联起来的。
闭包除外,JS 闭包中的变量值并不保存中栈内存中,而是保存在堆内存中。
实现颜色转换 'rgb(255, 255, 255)' -> '#FFFFFF' 的多种思路
仔细观察本题,本题可分为三个步骤:
从 rgb(255, 255, 255)
中提取出r=255
、g=255
、b=255
将 r
、g
、b
转换为十六进制,不足两位则补零组合 #
实现颜色转换 'rgb(255, 255, 255)' -> '#FFFFFF' 的多种思路
实现一个异步求和函数
简化:两数之和
加深:多数之和
优化:使用 Promise.all
一道腾讯手写题,如何判断 url 中只包含 qq.com
http://www.qq.com // 通过
http://www.qq.com.cn // 不通过
http://www.qq.com/a/b // 通过
http://www.qq.com?a=1 // 通过
http://www.123qq.com?a=1 // 不通过
由一道bilibili面试题看Promise异步执行机制
Promise
构造函数是同步执行的,then
方法是异步执行的.then
或者.catch
的参数期望是函数,传入非函数则会直接执行Promise
的状态一经改变就不能再改变,构造函数中的resolve
或reject
只有第一次执行有效,多次调用没有任何作用.then
方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为catch
是.then
第二个参数的简便写法当遇到 promise.then
时, 如果当前的Promise
还处于pending
状态,我们并不能确定调用resolved
还是rejected
,只有等待promise
的状态确定后,再做处理,所以我们需要把我们的两种情况的处理逻辑做成callback
放入promise
的回调数组内,当promise
状态翻转为resolved
时,才将之前的promise.then
推入微任务队列
es6 及 es6+ 的能力集,你最常用的,这其中最有用的,都解决了什么问题
我最常用的
ES6 的特性是使用最多的,包括类、模块化、箭头函数、函数参数默认值、模板字符串、解构赋值、延展操作符、Promise、let 与 const等等,这部分已经是开发必备了,没什么好说的
另外还有:
ES7 的 Array.prototype.includes()
ES8 的 async/await 、String padding: padStart()
和padEnd()
、Object.values()
ES9 的 Rest/Spread 属性、for await of、 Promise.finally()
ES10 的 Array.prototype.flat()
、Array.prototype.flatMap()
、String的trimStart()
trimEnd()
ES11 的 Promise.allSettled
、空值处理(??
)及可选链(?.
)ES12 的逻辑赋值操作符( ||=
、&&=
、??=
)、数字分隔符(1_000_000_000
)、Promise.any()
最有用的
ES6 的特性都很有用,ES7-ES11中,我比较感兴趣的是:
ES8 的 async/await ES9 的 for await of ES11 的 Promise.allSettled
、ES9 的Promise.finally()
、ES12 的Promise.any()
还有常用的逻辑操作:逻辑赋值操作符、数字分隔符、空值处理及可选链等都很大的简洁优化了我们的代码 其中,async/await 异步终极解决方案,
for await of
异步串行,Promise.allSettled
解决了Promise.all
的只要一个请求失败了就会抛出错误的问题,当我们一次发起多个请求时,所有结果都能返回,无论成功或失败,等等等,不了解的可以往下查找
es6 及 es6+ 的能力集,你最常用的,这其中最有用的,都解决了什么问题
Promise.allSettled 的作用,如何自己实现 Promise.allSettled
本文从四个方面循序渐进介绍
Promise.allSettled
:
Promise.all()
的缺陷引入 Promise.allSettled()
Promise.allSettled()
与Promise.all()
各自的适用场景手写 Promise.allSettled()
实现
Promise.allSettled 的作用,如何自己实现一个 Promise.allSettled
Promise.any 的作用,如何自己实现 Promise.any
本文从五个方面介绍
Promise.any
:
Promise.any
的作用Promise.any
应用场景Promise.any
vsPromise.all
Promise.any
vsPromise.race
手写 Promise.any
实现
Promise.any 的作用,如何自己实现一个 Promise.any
Promise.prototype.finally 的作用,如何自己实现 Promise.prototype.finally
Promise.prototype.finally()
是 ES2018 新增的特性,它回一个Promise
,在promise
结束时,无论Promise
运行成功还是失败,都会运行finally
,类似于我们常用的try {...} catch {...} finally {...}
Promise.prototype.finally 的作用,如何自己实现 Promise.prototype.finally
typeof 可以判断哪些类型?instanceof 做了什么?null为什么被typeof错误的判断为了'object'
typeof
操作符唯一的目的就是检查数据类型,但我们使用typeof
来判断引用类型变量时,无论是什么类型的变量,它都会返回Object
。为此,引入了instanceof
。
instanceof
与typeof
相比,instanceof
方法要求开发者明确的确认对象为某特定类型。即instanceof
用于判断引用类型属于哪个构造函数的方法。
typeof 可以判断哪些类型?instanceof 做了什么?null为什么被typeof错误的判断为了'object'
var、let、const 有什么区别
从作用域规则、重复声明/重复赋值、变量提升(hoisted)、暂时死区(TDZ)四个方面对比
var
、let
、const
声明的变量差异
WeakMap 和 Map 的区别,WeakMap 原理,为什么能被 GC?
Map
相对于WeakMap
:
Map
的键可以是任意类型,WeakMap
只接受对象作为键(null除外),不接受其他类型的值作为键Map
的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键;WeakMap
的键是弱引用,键所指向的对象可以被垃圾回收,此时键是无效的Map
可以被遍历,WeakMap
不能被遍历
WeakMap 和 Map 的区别,WeakMap 原理,为什么能被 GC?
更多
实现一个 sleep 函数,可从 Promise、Generator、Async/Await 等角度实现
手写 LRU 缓存策略,了解 Vue 的 keep-alive 实现
介绍下 Set、Map、WeakSet 和 WeakMap 的区别?
pdf
关注「三分钟学前端」:
回复「JS」,自动获取三分钟学前端 JS 篇小书(120+页)
回复「算法」,自动获取 github 2.9k+ 的前端算法小书
回复「面试」,自动获取 github 23.2k+ 的前端面试小书
回复「简历」,自动获取程序员系列的 120
套模版
最近开源了一个github仓库:百问百答,在工作中很难做到对社群问题进行立即解答,所以可以将问题提交至 https://github.com/Advanced-Frontend/Just-Now-QA ,我会在每晚花费 1 个小时左右进行处理,更多的是鼓励与欢迎更多人一起参与探讨与解答🌹