一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)

不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的几行代码,我们需要知道其输出内容和顺序。因为javascript是一门单线程语言,所以我们可以得出结论:

各位小伙伴在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于HTML/CSS/javaScript/Vue等多个知识点高级进阶干货需要的可以免费分享给大家,有需要者请进群点击进入1045267283

一个前端基础需要掌握的 28 个 JavaScript 技巧(第一章)

14. 实现函数 bind 方法
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


实现函数的 bind 方法核心是利用 call 绑定 this 指向,同时考虑了一些其他情况,例如

  • bind 返回的函数被 new 调用作为构造函数时,绑定的值会失效并且改为 new 指定的对象
  • 定义了绑定后函数的 length 属性和 name 属性(不可枚举属性)
  • 绑定后函数的 prototype 需指向原函数的 prototype(真实情况中绑定后的函数是没有 prototype 的,取而代之在绑定后的函数中有个 内部属性 [[TargetFunction]] 保存原函数,当将绑定后函数作为构造函数时,将创建的实例的 __proto__ 指向 [[TargetFunction]] 的 prototype,这里无法模拟内部属性,所以直接声明了一个 prototype 属性

15. 实现函数 call 方法
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


原理就是将函数作为传入的上下文参数(context)的属性执行,这里为了防止属性冲突使用了 ES6 的 Symbol 类型
16. 简易的 CO 模块
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


使用方法:
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


run 函数接受一个生成器函数,每当 run 函数包裹的生成器函数遇到 yield 关键字就会停止,当 yield 后面的 promise 被解析成功后会自动调用 next 方法执行到下个 yield 关键字处,最终就会形成每当一个 promise 被解析成功就会解析下个 promise,当全部解析成功后打印所有解析的结果,衍变为现在用的最多的 async/await 语法
17. 函数防抖
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


leading 为是否在进入时立即执行一次,原理是利用定时器,如果在规定时间内再次触发事件会将上次的定时器清除,即不会执行函数并重新设置一个新的定时器,直到超过规定时间自动触发定时器中的函数
同时通过闭包向外暴露了一个 cancel 函数,使得外部能直接清除内部的计数器

18. 函数节流
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


和函数防抖类似,区别在于内部额外使用了时间戳作为判断,在一段时间内没有触发事件才允许下次事件触发,同时新增了 trailing 选项,表示是否在最后额外触发一次
19. 图片懒加载
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


getBoundClientRect 的实现方式,监听 scroll 事件(建议给监听事件添加节流),图片加载完会从 img 标签组成的 DOM 列表中删除,最后所有的图片加载完毕后需要解绑监听事件
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


intersectionObserver 的实现方式,实例化一个 IntersectionObserver ,并使其观察所有 img 标签
当 img 标签进入可视区域时会执行实例化时的回调,同时给回调传入一个 entries 参数,保存着实例观察的所有元素的一些状态,比如每个元素的边界信息,当前元素对应的 DOM 节点,当前元素进入可视区域的比率,每当一个元素进入可视区域,将真正的图片赋值给当前 img 标签,同时解除对其的观察
20. new 关键字
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


21. 实现 Object.assign
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)

22. instanceof
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


原理是递归遍历 right 参数的原型链,每次和 left 参数作比较,遍历到原型链终点时则返回 false,找到则返回 true
23. 私有变量的实现
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


使用 Proxy 代理所有含有 _ 开头的变量,使其不可被外部访问
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


通过闭包的形式保存私有变量,缺点在于类的所有实例访问的都是同一个私有变量
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


另一种闭包的实现,解决了上面那种闭包的缺点,每个实例都有各自的私有变量,缺点是舍弃了 class 语法的简洁性,将所有的特权方法(访问私有变量的方法)都保存在构造函数中
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


通过 WeakMap 和闭包,在每次实例化时保存当前实例和所有私有变量组成的对象,外部无法访问闭包中的 WeakMap,使用 WeakMap 好处在于当没有变量引用到某个实例时,会自动释放这个实例保存的私有变量,减少内存溢出的问题
24. 洗牌算法
早前的 chrome 对于元素小于 10 的数组会采用插入排序,这会导致对数组进行的乱序并不是真正的乱序,即使最新的版本 chrome 采用了原地算法使得排序变成了一个稳定的算法,对于乱序的问题仍没有解决
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


通过洗牌算法可以达到真正的乱序,洗牌算法分为原地和非原地,图一是原地的洗牌算法,不需要声明额外的数组从而更加节约内存占用率,原理是依次遍历数组的元素,将当前元素和之后的所有元素中随机选取一个,进行交换
25. 单例模式
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


通过 ES6 的 Proxy 拦截构造函数的执行方法来实现的单例模式
26. promisify
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


使用方法:
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


promisify 函数是将回调函数变为 promise 的辅助函数,适合 error-first 风格(nodejs)的回调函数,原理是给 error-first 风格的回调无论成功或者失败,在执行完毕后都会执行最后一个回调函数,我们需要做的就是让这个回调函数控制 promise 的状态即可
这里还用了 Proxy 代理了整个 fs 模块,拦截 get 方法,使得不需要手动给 fs 模块所有的方法都包裹一层 promisify 函数,更加的灵活
27. 优雅的处理 async/await
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


使用方法:
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


无需每次使用 async/await 都包裹一层 try/catch ,更加的优雅,这里提供另外一个思路,如果使用了 webpack 可以编写一个 loader,分析 AST 语法树,遇到 await 语法,自动注入 try/catch,这样连辅助函数都不需要使用
28. 发布订阅 EventEmitter
 

一个前端基础需要掌握的 28 个 JavaScript 技巧(第二章)


通过 on 方法注册事件,trigger 方法触发事件,来达到事件之间的松散解耦,并且额外添加了 once 和 off 辅助函数用于注册只触发一次的事件以及注销事件
29. 实现 JSON.stringify(附加)
使用 JSON.stringify 将对象转为 JSON 字符串时,一些非法的数据类型会失真,主要表现如下

  • 如果对象含有 toJSON 方法会调用 toJSON
  • 在数组中
  1. 存在 Undefined/Symbol/Function 数据类型时会变为 null
  2. 存在 Infinity/NaN 也会变成 null
  • 在对象中
  1. 属性值为 Undefined/Symbol/Function 数据类型时,属性和值都不会转为字符串
  2. 属性值为 Infinity/NaN ,属性值会变为 null
  • 日期数据类型的值会调用 toISOString
  • 非数组/对象/函数/日期的复杂数据类型会变成一个空对象
  • 循环引用会抛出错误

相关CSS知识点:灵活运用CSS开发技巧(第一章)

在此小编再次感谢大家对我的支持,需要更多相关资料,视频请加群点击进入1045267283