Skip to main content

a 标签默认时间禁用后做了什么才能实现跳转

简单来说,找到该控件,添加点击 click 监听事件,使用 location.href 进行跳转。

let domArr = document.getElementsByTagName("a")
[...domArr].forEach(item=>{
item.addEventListener('click',function(){
location.href=this.href
})
})

axios 实际上做了什么事情

Axios 是一个基于 PromiseHTTP 客户端,用于 node.js 和浏览器。 它是同构的(= 它可以在具有相同代码库的浏览器和 node.js 中运行)。 在服务器端它使用原生 node.js http 模块,而在客户端(浏览器)它使用 XMLHttpRequests。它本身具有以下特征

  • 从浏览器中创建 XMLHttpRequest

  • 支持 Promise API

  • 客户端支持防止 CSRF

  • 提供了一些并发请求的接口(重要,方便了很多的操作)

  • node.js 创建 http 请求

  • 拦截请求和响应

  • 转换请求和响应数据

  • 取消请求

  • 自动转换 JSON 数据

更多请见:axios docs

cookie、localstroage、sessionstroage 区别

cookie: 大小受限,只有 4kb 的大小,服务器端和浏览器;并且每次发送一个新的页面的时候 cookie 都会发送过去,这样无形浪费了带宽; cookie 还需要指定作用域,不可以跨域调用

localstorage: 是一个持久化的本地存储,除非强制删除,否则数据永远不会过期,支持 getpost 请求(存储在 2.5MB 到 10MB 之间);不提供搜索功能,不能建立自定义的索引

sessionStroage: 是本地的一个会话级别的存储,在页面打开的时候创建,页面关闭的时候销毁

diff 算法

diff 算法#

在某一时间节点调用 React 的 render() 方法,会创建一棵由 React 元素组成的树。在下一次 stateprops 更新时,相同的 render() 方法会返回一棵不同的树。React 需要基于这两棵树之间的差别来判断如何高效的更新 UI,以保证当前 UI 与最新的树保持同步。

此算法有一些通用的解决方案,即生成将一棵树转换成另一棵树的最小操作次数。然而,即使使用最优的算法,该算法的复杂程度仍为 O(n3),其中 n 是树中元素的数量。

如果在 React 中使用该算法,那么展示 1000 个元素则需要 10 亿次的比较。这个开销实在是太过高昂。于是 React 在以下两个假设的基础之上提出了一套 O(n) 的启发式算法:

  1. 两个不同类型的元素会产生出不同的树;
  2. 开发者可以通过设置 key 属性,来告知渲染哪些子元素在不同的渲染下可以保存不变;

正是基于此设计概念,所以 React diff 算法只对同层进行比较,故将复杂度降低到 O(n) 而其体现形式即如下:

  • 对比不同类型的元素(当根节点为不同类型的元素时,React 会拆卸原有的树并且建立起新的树)
  • 对比同一类型的元素(仅对比更新有改变的属性)
  • 对比同一类型的组件元素(组件实例会保持不变,因此可以在不同的渲染时保持 state 一致)
  • 对子节点进行递归(默认情况下,React 会同时遍历两个子元素的列表;当产生差异时,生成一个 mutation

对子节点的递归涉及到我们为什么要为子元素设置 key ?即帮助 React 使用 key 来匹配原有树上的子元素以及最新树上的子元素。至于为什么不用下标作为 key ,我想读者加以思考便会知道

由于 React 依赖启发式算法,因此当以下假设没有得到满足,性能会有所损耗。

  1. 该算法不会尝试匹配不同组件类型的子树。如果你发现你在两种不同类型的组件中切换,但输出非常相似的内容,建议把它们改成同一类型。在实践中,我们没有遇到这类问题。
  2. Key 应该具有稳定,可预测,以及列表内唯一的特质。不稳定的 key(比如通过 Math.random() 生成的)会导致许多组件实例和 DOM 节点被不必要地重新创建,这可能导致性能下降和子组件中的状态丢失。

更多设计思想与实现细节请查看 协调 [Diff 算法](

flat、拍平数组、自己实现拍平数组的效果

这里只提供两个比较简单的实现,后面还会涉及到使用reduce和栈、使用Generator、原型链等等,详细见:面试官连环追问:数组拍平(扁平化) flat 方法实现 - 知乎 (zhihu.com)

  1. 最简单的遍历实现
const arr = [1, 2, 3, 4, [1, 2, 3, [1, 2, 3, [1, 2, 3]]], 5, 'string', { name: '弹铁蛋同学' }]
// concat + 递归
function flat(arr) {
let arrResult = []
arr.forEach((item) => {
if (Array.isArray(item)) {
arrResult = arrResult.concat(flat(item)) // 递归
// 或者用扩展运算符
// arrResult.push(...arguments.callee(item));
} else {
arrResult.push(item)
}
})
return arrResult
}
flat(arr)
// [1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 1, 2, 3, 5, "string", { name: "弹铁蛋同学" }];
  1. 传入数组控制递归层数
// reduce + 递归
function flat(arr, num = 1) {
return num > 0
? arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? flat(cur, num - 1) : cur), [])
: arr.slice()
}
const arr = [1, 2, 3, 4, [1, 2, 3, [1, 2, 3, [1, 2, 3]]], 5, 'string', { name: '弹铁蛋同学' }]
flat(arr, Infinity)
// [1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 1, 2, 3, 5, "string", { name: "弹铁蛋同学" }];

Flex 布局有哪些属性?分别代表什么意思?

指定容器为 flex 布局:

.box {
display: flex;
}

容器的属性有以下 6 个:

  • flex-direction:决定主轴的方向(即项目的排列方向)
flex-direction: row | row-reverse | column | column-reverse;
  • flex-wrap:(flex-wrap属性定义,如果一条轴线排不下,如何换行)
flex-wrap: nowrap | wrap | wrap-reverse;
  • flex-flow:(flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
flex-flow: <flex-direction> || <flex-wrap>;
  • justify-content:(justify-content属性定义了项目在主轴上的对齐方式)
justify-content: flex-start | flex-end | center | space-between | space-around;
  • align-items:(align-items属性定义项目在交叉轴上如何对齐)
align-items: flex-start | flex-end | center | baseline | stretch;
  • align-content:(align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用)
align-content: flex-start | flex-end | center | space-between | space-around | stretch;

Html 标签 b 和 strong 的区别

两者在网页中显示效果大致一样,实际目的不同。

<b> 标签对应为 bold,文本加粗,仅仅为了加粗文本,是一种样式需求。

<strong> 标签意思是加强,表示该文本比较重要,提醒读者注意,然后浏览器将其加粗注意显示。

最重要的区别就是样式标签和语义化标签的区别。

Html5 有哪些新特性?如何处理新标签的浏览器兼容问题?如何区分 Html 和 Html5?

Html5 新特性

  • 拖拽释放APIDrag and drop
  • 更好的语义化内容标签(headernavfooterasidearticlesection
  • 音频、视频 APIaudiovideo
  • 画布(CanvasAPI
  • 地理(GeolocationAPI
  • 本地存储 localstorage、会话存储 sessionstorage
  • 表单控件,calendardatetimeemailurlsearch
  • 新技术 webworkerwebsocket

如何处理新标签浏览器兼容性

  • 做好错误处理,如果显示不了且一定需要该功能,是否可以用其他内容填充。
  • 引入已经支持这些标签的封装好的库(html5shiv.js

如何区别 Html 和 Html5

  • 查看文档头部doctype。旧版本会声明为xhtml1-transitional.dtd
  • 结构语义化,旧版本一般使用<div id="header"></div>,使用 classname 来命名,新版本使用结构化语言标签。

HTTP 里面的缓存机制

两种缓存方式,根据响应的 header 内容来决定

  • 强缓存(状态码:200):浏览器不向服务器发送任何请求,直接从本地缓存中读取文件并返回(相关字段:Cache-ControlExpires

  • 协商缓存(状态码:304):浏览器发送请求到服务器,通过服务器来告知缓存是否可用(相关字段:Last-Modified/If-Modified-SinceEtag/If-None-Match

缓存相关 header

Cache-ControlExpiresLast-Modified/If-Modified-SinceEtag/If-None-Match

img

详情请见:彻底理解浏览器的缓存机制