JavaScript 学习 | 青训营笔记

100 阅读4分钟

这是我参与「第四届青训营」笔记创作活动的第 2 天

一、本堂课重点内容:

  • JavaScript 三个原则
  • 编程范式
  • 部分算法

二、详细知识点介绍:

JavaScript 三个原则

各司其责 - 让三大件职能分离

  • 应当避免不必要的由 JS 直接操作样式
  • 纯展示类交互寻求零 JS 方案

组件封装 - 封装性、正确性、扩展性、复用性

基本方法

  • 结构设计 - HTML
  • 展现效果 - CSS
  • 行为设计 - JavaScript

    • API (功能)
    • Event (控制流)

重构方向

  • 插件化 - 让组件更加的灵活

    • 将控制元素抽取成插件

    • 插件与组件之间通过依赖注入方式建立联系

    • 可以添加以下函数到类内进行注册插件操作

      • registerPlugins(...plugins){
          plugins.forEach(plugin => plugin(this));
        }
        
  • 模板化 - 将 HTML 模板化更易于扩展

    • 可以在类内创建一个 render() 函数
  • 抽象化 - 通过编写一个抽象类当作接口进行操作

过程抽象 - 应用函数式编程思想

  • 用来处理局部细节控制的一些方法

高阶函数(HOF)

  • 让功能需求覆盖到不同的事件处理,将事件抽象成高阶函数则为一种过程抽象
  • 高阶函数一般为纯函数
结构
function HOF0(fn) {
  return function(...args) {
    return fn.apply(this, args);
  }
}
  • 以函数作为参数
  • 以函数作为返回值
  • 常用于作为函数装饰器
常用高阶函数
  • Once - 操作次数限制
  • Throttle - 节流(限制操作频率)
  • Debounce - 防抖函数
  • Consumer - 计算函数
  • Iterative - 批量操作函数
例子 - 操作次数限制
function once(fn) {
  return function(...args) {
    if(fn) {
      const ret = fn.apply(this, args);
      fn = null;
      return ret;
    }
  }
}

const foo = once(() => {
  console.log('bar');
});

foo();
foo();
foo();

虽然使用了三次 foo 函数,但是实际上仅会输出一次 "bar" 。原因在于 foo 的返回值是一个函数而该函数在调用一次过后则变为 NULL ,导致第二次在判断时为 False 无法进入从而实现限制操作次数的功能

纯函数

特点
  1. 如果函数的调用参数相同,则永远返回相同的结果。它不依赖于程序执行期间函数外部任何状态或数据的变化,必须只依赖于其输入参数。
  1. 该函数不会产生任何可观察的副作用
  1. 纯函数相较于非纯函数有较高的可维护性

编程范式

JavaScript 支持命令式声明式两种

命令式范式 - 告诉程序如何做

  • 面向过程
  • 面向对象

声明式范式 - 告诉程序做什么

声明式范式的代码会较为简洁

  • 函数式编程

    • 拥有更高的可扩展性
  • 逻辑式编程

判断是否为 4 的幂

位与运算符 &

  • 用于对两个二进制操作数逐位进行比较
第一个数位值第二个数位值运算结果
111
100
010
000
  • 当数为 2 的幂时,该数的二进制仅有一个 1
  • 当数为奇数时,该数的二进制的个位为 1 ,反之亦然

方法一

function isPowerOfFour(num){
  num = parseInt(num);
  return num > 0 &&
         (num & (num - 1)) === 0 &&
         (num & 0xAAAAAAAAAAAAA) === 0;
}

解析

num > 0
  • 4 的幂均大于 0
num & (num - 1) === 0

num 和 (num - 1) 必然其中一个为奇数,一个为偶数。

因此两者进行运算时,必然会消去 num 的一个 1

又因为当该数为 2 的幂时,该数的二进制仅有一个 1,因此运算结果即为 0

(num & 0xAAAAAAAAAAAAA) === 0
  • 0xAAAAAAAAAAAAA 转二进制为 1010101010101010101010101010101010101010101010101010

因为 4 的幂的数的二进制(从右往左数)偶数位不能为 1

若偶数位包含 1 则运算结果不为 0 故能判断该值是否为 4 的幂

其中,A 的个数取决于 JavaScript 的精度为 64 位的浮点数,其中有 11 位的小数位,因此整数的精度为 53 位

方法二

function isPowerOfFour(num) {
  num = parseInt(num).toString(2);
  return /^1(?:00)*$/.test(num);
}

解析

#2 - 将 num 转换为一个二进制字符串

#3 - 进行正则表达式匹配,若 1 后有偶数个 0 则为真,反之为假

分红包

切西瓜法

  • 每次切都切最大的一块
  • 时间复杂度 O(M*N)
  • 缺点在于小的那一块不会进行切割

抽牌法

  • 时间复杂度 O(N)
  • 缺点在于空间复杂度较高(需要创建随机数列)
  1. 生成一个随机数列
  1. 用生成器从数列中取若干个
  1. 将指传递到数组并将数组排序
  1. 通过前减后来获取红包值

三、引用参考:

  1. JavaScript: 什么是纯函数以及为什么要用纯函数?_慕课手记