最近刷面试题目的一点总结

287 阅读5分钟

JS 部分

  1. querySelector 和querySelectorAll 方法

querySelector 方法返回第一个匹配的DOM元素,如果不匹配,返回NULL。querySelectorAll 方法则返回 一个NodeList 的静态实例。NodeList 是一个类数组对象,可以使用... 符号来转换为数组。

  • querySelectorAll('*') 可以返回所有的HTML NODE节点。
  1. 关于textContent,innerText,innerHTML 的区别
  • innerText 可以自动对字符串进行HTML编码。
var p = document.getElementById('p-id');
p.innerText = '<script>alert("Hi")</script>';
// script 标签可以自动转义
// <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p >
  • textContent

textContent 除和innerText 有对字符串进行HTML编码的功能外,还可以返回隐藏的文本,比如换行符,Tab符等。

  • innerHTML

innerHTML 与前面两个不同,它可以用于改变HTML元素内部的结构

  1. 关于== 号比较操作符
  • 当==号左右两边操作数是不同类型的时候,会进行隐式类型转换,转换为同一种类型中,再进行比较。
    • 基本数据类型,相互比较,一般都是将其转换数字类型后,然后再进行比较。
    • 引用类型与基本类型相互比较,则是将引用类型调用[Symbol.toPrimitive]、valueOf()或者toString() 方法后,然后进行比较。
    • [Symbol.toPrimitive] 优先级比valueOf 高,valueOf 优先级比toString() 优先级高。
var a1 = {
    // valueOf() {
    //     return 2;
    // },
    toString() {
        return 4;
    },
    // [Symbol.toPrimitive]() {
    //     return 3;
    // }
};
console.log('a1:', a1 == 4);
  1. this 存在四种绑定规则
  • 默认绑定

当函数单独调用的时候, this 指代window.(非严格模式下,严格模式下,指向undefined).

  • 隐式绑定

函数是哪个对象调用的,则函数中的this 指向哪个对象。

  • new 绑定

使用new 操作符后, 构造函数中的this 指向通过new 生成的对象实例。

  • 显式绑定

就是使用call,apply,bind 方法,显示更改调用函数的对象。

  • 四种绑定规则的优先级
  1. new 绑定/显式绑定 > 隐式绑定
  2. 隐式绑定 > 默认绑定。
//new>隐式
const obj2 = {
    name: '时间跳跃',
    fn: function () {
        this.name = '听风是风';
    }
};
let echo = new obj2.fn();
console.log('echo.name', echo.name);//听风是风
  1. 关于正则表达式 (?<xx>:) 表示的是一种匹配
// ?: 
const protocol = "(?<protocol>https?:)";
const protocolReg = new RegExp(`${protocol}`, 'i');
const result = protocolReg.exec('https://localhost:3000/name?age=45#123456');
console.log('result', result);

const host = "(?<host>(?<hostname>[^/#?:]+)(?::(?<port>\\d+))?)";
const path = "(?<pathname>(?:\\/[^/#?]+)*\\/?)";
const search = "(?<search>(?:\\?[^#]*)?)";
const hash = "(?<hash>(?:#.*)?)";
const reg = new RegExp(`^${protocol}\/\/${host}${path}${search}${hash}$`);

function execURL(url) {
  const result = reg.exec(url);
  console.log('result', result);
  if (result) {
    result.groups.port = result.groups.port || "";
    return result.groups;
  }
  return {
    protocol: "",
    host: "",
    hostname: "",
    port: "",
    pathname: "",
    search: "",
    hash: "",
  };
}
const segments = execURL('https://localhost:8080/?a=b#xxxx');
console.log(`seagements`, segments);
  1. vue2 和react以及vue3 diff算法的相同点和不同点:
  • 相同点: 都是同级比较,不跨级比较。如果发现tag 不同,则直接删掉重建。 key 之所以重要,是因为如果key 相同,类型也相同,则被认为是同一个节点,会直接复用,移动有关元素,会让渲染效率更高一点。

  • 不同点:

vue2: 使用的是递归和双指针的算法。其实就是有四个指针,如果指针指向的节点相同,则头指针向右走一步,尾指针向左走一步。直到两个指针相遇。

React: 当旧的节点和新的节点相比较的时候,旧的指针和新的指针,都分别指向节点的开始,旧节点,遵循只向右移动的原则。如果需要向左移,则跳过。

vue3: vue3 在vue2的基础上,使用了最长递增子序列

webpack 部分

  1. HMR 热更新的原理:

分为加载阶段和更新阶段,两个阶段。 加载阶段,本地文件,经过webpack 编译之后,会被webpack打包成bundle,然后,发给boundle server,这个时候浏览器就可以通过服务器的方式访问页面了。开启热更新了后,bundle中,还会生成一个HRM RUNtime 客户端。同时在本地服务中,开启一个HRM Server 服务端。(对应下图的1->2->4阶段)

更新阶段,当用户更改代码后,HRM Server会将更改的模块信息,以json 的信息,传递给HRM runtime 客户端。客户端收到对应的信息后,会重新更新boundle,然后发送给boundle Server,这个时候,浏览器中看到的页面就发生了变化。(对应下图的1->2->3->4->8)

热更新.PNG

HTTP 协议部分

  • HTTP 1.1 与HTTP 2.0 与HTTP 1.0

HTTP 1.0 是每次客户端和服务端都建立短暂的连接,服务器完成请求处理后,立刻断开TCP连接。

一个HTML 文件的访问,包含了多次的请求和响应,每次都需要重新建立连接,关闭连接,造成了性能上的损耗。如果需要建立一个长连接,则需要设置一个非标准的Connection 字段: keep-alive 字段。

HTTP 1.1 协议: HTTP 1.1 协议默认支持长连接。一个长连接上,可以支持多个请求和响应,减少了建立和关闭连接的延迟和消耗。服务端需要按照顺序,一一来处理客户端发送过来的请求,可能造成阻塞。 HTTP 1.1 协议在HTTP1.0 的基础上增加了更多的请求和响应头字段。比如range 字段,允许客户端请求服务端的部分资源,引入了更多的缓存控制策略和相关头,如If-Match,If-None-Match,If-Unmodified-Since。

HTTP 2.x 协议: 2.x 协议增加了头部压缩,二进制分帧,服务器推送和多路复用。HTTP2.x 为了解决Http1.1 响应阻塞的问题,就使用了多路复用的技术,这样就保证了客户端和浏览器端,可以同时发送多个请求和响应,而且不用按照顺序一一对应。