一.网络

  1. http 与 https的不同
  2. 什么是头部阻塞、http2解决什么问题
  3. 强缓存与协商缓存

二.CSS

三.JS基础

  1. js基本数据类型与复杂数据类型
    基本数据类型:
    undefined number string boolean bigInt
    复杂数据类型:
    Object Function Array Set Symbol
  2. instanceof 能否判断基本数据类型?
    instanceof 用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。所以不可以判断基础数据类型。
    手写instanceof
function myInstance(left, right) {
  let proto = left.__proto__;
  let prototype = right.prototype;

  while(proto) {
    if(proto === prototype)  {
       return true;
    } else {
       proto = proto.__proto__;
    }
  }
  
  return false;
}
  1. 显式原型(prototype)、隐式原型(__proto__)、原型链
    显示原型是函数上的一个对象实例、隐式原型是每一个对象实例上的一个属性指向构造函数的显示原型(prototype)。
    js可以通过原型链实现继承
function _extends (subClass, superClass){
  subClass.prototype = Object.create(superClass.prototype);
  subClass.prototype.constructor = subClass;
  Object.setPrototypeOf(subClass, superClass);
}

function superClass() {}
function subClass(spec) {
  let _this = superClass.call(this) || this;
  _this.spec = spec;

  return _this;
}

_extends(subClass , superClass);
  1. 写一个自定义的变量类型判断函数
function myType(o) {
  let tType  = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
     
   return tType;
}
  1. '1'.toString() 为什么可以调用
    其实执行了如下的转换

    let s = new Object('1');
    s.toString();
    s = null;
  2. 0.1 + 0.2 === 0.3 嘛?为什么?

     不相等,因为计算机用二进制表示0.1时无法精确表示,会是一个无限循环数,0.2也是类似的;相加之后也是个无限循环的二进制数,但js的Number精度有限,不能完全与0.3相等。
     对于这种数学比较,可以使用两端相减对比一个极小数,如 Number.EPSILON。

    Polyfill

    if (Number.EPSILON === undefined) {
     Number.EPSILON = Math.pow(2, -52);
    }
  3. 什么是 BigInt? 为什么需要 BigInt?

     bigInt是js中用于表示任意长度整型的基本数据类型。
     因为传统的Number类型是一个64位双精度浮点型,能够表示的数字范围是2^53-1到-(2^53-1),这样在处理高精度极大数或极小数时就会出现溢出的问题。由此提出了bigInt类型,在处理高精度时间戳,超长的数字ID等就可以直接使用bigInt进行存储,而不需要使用String存储了。
    
  4. ==、===和Object.is的区别
    == 在比较两端边变量如遇到两端数据类型不同时会自动进行类型转换,转换后再进行比较。
    转换规则为:1.如果两端为boolean、string、number三者中任意两者时,优先转换为数字进行比较。2.null和undefined除了自身相等外,两者也相等。
    ===对数据类型和值都进行判断,奇怪点是NaN === NaN 返回false,-0 === +0 返回true。
    Object.is是ES6中定义的一个新方法,表现和===基本一致,除了NaN === NaN会返回true,-0 === +0 会返回false 外。
  5. 复杂类型转化为基本类型的过程

     会先选择调用复杂类型的valueOf方法,如果该方法返回的是基本数据类型则使用该返回值进行强制类型转换;没有则使用toString方法的返回值进行强制类型转化;如果还没有就会产生TypeError的错误。
    
  6. 输入二进制字符串,如: 0101100;输出字符串0和1相间的自串需要最小交换几次位置
function minSwitching(str) {
  let style1 = {'0': 0, '1': 0}, //  010101...
    style2 = {'0': 0, '1': 0};   //` 101010...
  const len = str.length;
  
  for(let i = 0, j = 0; i < len; i++) {
    let aChart = str.charAt(i);

    if(j === 0) {
      if(aChart === '0') {
        style2['1'] += 1 
      } else {
        style1['0'] += 1 
      }
      j = 1;
    } else {
      if(aChart === '0') {
        style1['1'] += 1 
      } else {
        style2['0'] += 1 
      }
      j = 0;
    }
  }
 
  let ret1 = style1['0'] === style1['1'] ? style1['0'] : -1;
  let ret2 =  style2['0'] === style2['1'] ? style2['0'] : -1;
  
  if(ret1 !== -1 && ret2 !== -1) {
    return ret1 < ret2 ? ret1 : ret2;
  } else {
    return ret1 !== -1 ? ret1 : ret2;
  }
}
  1. deepClone:
function deepClone(obj) {
  let ret;
  switch(typeof obj) {
     case "number":
     case "string":
     case "bool":
     case "undefined":
     case "bigint":
     case "symbol":
        ret = obj;
        break;
    case "object":
       if(obj === null) {
         ret = null;
       } else if(obj instanceof Map) {
         ret = new Map();
         obj.forEach((value, key) => {
            ret.set(key, deepClone(value));
         });
       } else if(Array.isArray(obj)) {
            ret = obj.map(item => deepClone(item));
        } else if(obj instanceof Set) {
            ret = new Set();
            obj.forEach(value => {
                ret.add(deepClone(value));
            });
        } else {
            ret = {};
            for(let key in obj) {
                if(obj.hasOwnProperty(key)) {
                    ret[key] = deepClone(obj[key]);
                }
            }
        }

  }

return ret;
}

12节流和防抖:
节流和防抖都是用来控制函数执行速率的函数,不同点是节流为在一定时间阀值内,多次触发只响应一次,防抖则是在一定时间阀值内,连续触发将导致函数持续不响应。

function throttle(func, delay) {
    let timer = null;
    return function(args) {
        if(timer == null) {
            setTimeout(() => {
                func.apply(this, args);
                timer = null;
            }, delay)
        }
    }
}

function debounce(func, delay) {
    let timer = null;
    return function(args) {
        clearTimeout(timer);
        setTimeout(func.bind(this, args), delay);
    }
}

节流用于控制函数频繁响应,一般用于监听鼠标滚动,页面尺寸变化等事件上,保证响应函数在一定时间间隔只执行一次。
防抖一般用于在一系列连续动作结束后再响应的场景,如用户持续输入、用户连续点击按钮等。可以保证在用户持续操作结束后再响应。

四.前端框架

  1. Vue源码,手写数据劫持(Object.defineProperty)
  2. react(https://blog.csdn.net/weixin_46463785/article/details/131352147)、react-hook原理、react性能优化
  3. mpx、taro
  4. react-router、vue-router等的源码

    五.前端工程化

  5. webpack
  6. happypack、treeshaking
  7. AMD、CMD、commonjs、es6模块化
  8. git 常用命令:
    撤销本地commit(还没有push到远端):

     git reset --soft head^ 软撤销,head^是指当前commit,可以改成任意commit id
     git reset --hard head^ 硬撤销,彻底丢掉这次提交的全部修改
     git reset 不加参数,本次修改就会回到add之前的状态

    将本地文件修改暂时保存:

     git stash 将修改的文件保存至缓存中,git stash pop 将缓存中的修改恢复出来

    六.前端实践

  9. better-scroll
  10. 前端性能优化
  11. 小程序性能优化(实际项目)
  12. 移动端调试神奇eruda
  13. webGis相关:基础算法 学习资料 坐标系变换的基础知识 从零打造webgis
  14. 前端性能分析 webvitals
  15. 纯js实现的前端文字识别库:github.com/naptha/tesseract.js
  16. r-tree,跨端js-bridge,直接调用c++的方法。
  17. 前端模块化:https://juejin.cn/post/7252992621436829754?searchId=202308101...
  18. jsbridge: https://zhuanlan.zhihu.com/p/438763800
  19. 脚手架:https://juejin.cn/post/7260144602471776311#heading-16
  20. 前端基建:https://juejin.cn/post/7256879435339628604
  21. 自动化测试:https://puppeteer.bootcss.com/

           https://zhuanlan.zhihu.com/p/76237595
           monkey等
  22. 前端性能监控
  23. webContainer 浏览器跑node https://webcontainers.io/guides/quickstart

七.面试复盘

1.react相关、原理、differ、fiber、hook的原理。
2.讲框架原理的时候可以从更高层级去抽象,从同一的MVVM层去讲,react、vue万变不离其宗。
3.webpack相关的再整理整理吧,准备几条案例既可,如service-worker。


牛刀杀鸡
3 声望0 粉丝

« 上一篇
操作系统学习
下一篇 »
前端路由