获得徽章 7
#每天一个知识点#
setState 同步还是异步
setState 本身代码的执行肯定是同步的,这里的异步是指是多个 state 会合成到一起进行批量更新。
同步还是异步取决于它被调用的环境。

如果 setState 在 React 能够控制的范围被调用,它就是异步的。比如合成事件处理函数,生命周期函数, 此时会进行批量更新,也就是将状态合并后再进行 DOM 更新。
如果 setState 在原生 JavaScript 控制的范围被调用,它就是同步的。比如原生事件处理函数,定时器回调函数,Ajax 回调函数中,此时 setState 被调用后会立即更新 DOM 。
展开
评论
#每天一个知识点#
GET 和 POST 的区别。
从缓存的角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
从编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
从参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
从幂等性的角度,GET 是幂等的,而 POST 不是。(幂等表示执行相同的操作,结果也是相同的)
从 TCP 的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
展开
1
#每天一个知识点#
浏览器的垃圾回收机制
有两种垃圾回收策略:
标记清除:标记阶段即为所有活动对象做上标记,清除阶段则把没有标记(也就是非活动对象)销毁。
引用计数:它把对象是否不再需要简化定义为对象有没有其他对象引用到它。如果没有引用指向该对象(引用计数为 0),对象将被垃圾回收机制回收。
展开
评论
#每天一个知识点#
async/await 和 Promise 的关系
async/await 是消灭异步回调的终极武器。
但和 Promise 并不互斥,反而,两者相辅相成。
执行 async 函数,返回的一定是 Promise 对象。
await 相当于 Promise 的 then。
tru...catch 可捕获异常,代替了 Promise 的 catch。
展开
评论
#每天一个知识点#
instanceof原理:
作用:
①用于判断某个实例是否属于某构造函数

②在继承关系中用来判断一个实例是否属于它的父类型或者祖先类型的实例

查找构造函数的原型对象是否在实例对象的原型链上,如果在返回true,如果不在返回false。
说白了,只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false。
展开
评论
#每天一个知识点#
关系型数据库和非关系型数据库的区别:

1.数据存储方式:非关系型数据库的存储方式是KEY-VALUE的形式、文档等形式,而关系型数据库只支持单一的存储方式。

2.查询效率:关系型数据库存储于磁盘,非关系型数据库存储于缓存,效率比关系型数据库更高。

3.事务:关系型数据库支持事务处理,可进行事务回滚。

4.成本:非关系型数据库基本是开源的,不需要像oracle花费大量的成本购买
展开
评论
#每天一个知识点#
interface和type的主要区别
定义类型范围不同
interface 只能定义对象类型或者接口当名字的函数类型

type可以定义任何类型包括基础类型、联合类型、交叉类型、元组
展开
评论
#每天一个知识点#
HTTP状态码301与302有什么区别?
301:(永久移动)请求的网页已被永久移动到新位置。服务器返回此响应(作为对GET或HEAD请求的响应)时,会自动将请求V到新位置。

302:(临时移动)服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。此代码与响应GET和HEAD请求的301代码类似,会自动将请求者转到不同的位置。
展开
评论
#每天一个知识点#
new 实现

首先创一个新的空对象。
根据原型链,设置空对象的 __proto__ 为构造函数的 prototype 。
构造函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性)。
判断函数的返回值类型,如果是引用类型,就返回这个引用类型的对象。
展开
评论
#每天一个知识点#
作用域与作用域链
作用域:规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。换句话说,作用域决定了代码区块中变量和其他资源的可见性。(全局作用域、函数作用域、块级作用域)
作用域链:从当前作用域开始一层层往上找某个变量,如果找到全局作用域还没找到,就放弃寻找 。这种层级关系就是作用域链
展开
评论
#每天一个知识点#
line-height 如何继承?
父元素的 line-height 写了具体数值,比如 30px,则子元素 line-height 继承该值。
父元素的 line-height 写了比例,比如 1.5 或 2,则子元素 line-height 也是继承该比例。
父元素的 line-height 写了百分比,比如 200%,则子元素 line-height 继承的是父元素 font-size * 200% 计算出来的值。
展开
评论
#每天一个知识点#
在浏览器中,有以下几种常见的缓存:

1.强制缓存:通过设置Cache-Control和Expires等响应头实现,可以让浏览器直接从本地缓存中读取资源而不发起请求。

2.协商缓存:通过设置Last-Modified和ETag等响.应头实现,可以让浏览器发送条件请求,询问服务器是否有更新的资源。如果服务器返回304NotModified响应,则表示客户端本地缓存仍然有效,可直接使用缓存的资源。

3. Service Worker缓存: Service Worker是一种特殊的JS脚本,可以拦截网络请求并返回缓存的响应,以实现离线访问和更快的加载速度等功能。 4. Web Storage缓存:包括localStorage和sessionStorage。localStorage 用于存储用户在网站_上的永久性数据,而sessionStorage则用于存储用户会话过程中的临时数据。
展开
评论
#每天一个知识点#
如何减少重排和重绘?

最小化重绘和重排,比如样式集中改变,使用添加新样式类名 .class 或 cssText 。
批量操作 DOM,比如读取某元素 offsetWidth 属性存到一个临时变量,再去使用,而不是频繁使用这个计算属性;又比如利用 document.createDocumentFragment() 来添加要被添加的节点,处理完之后再插入到实际 DOM 中。
使用 **absolute** 或 **fixed** 使元素脱离文档流,这在制作复杂的动画时对性能的影响比较明显。
开启 GPU 加速,利用 css 属性 transform 、will-change 等,比如改变元素位置,我们使用 translate 会比使用绝对定位改变其 left 、top 等来的高效,因为它不会触发重排或重绘,transform 使浏览器为元素创建⼀个 GPU 图层,这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘
展开
1
#每天一个知识点#
重排(reflow)和重绘(repaint)的理解
简单地总结下两者的概念:

重排:无论通过什么方式影响了元素的几何信息(元素在视口内的位置和尺寸大小),浏览器需要重新计算元素在视口内的几何属性,这个过程叫做重排。
重绘:通过构造渲染树和重排(回流)阶段,我们知道了哪些节点是可见的,以及可见节点的样式和具体的几何信息(元素在视口内的位置和尺寸大小),接下来就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘。
展开
评论
#每天一个知识点#
CSS中的盒模型有以下两种:标准盒模型、IE(替代)盒模型。
两种盒子模型都是由 content + padding + border + margin 构成,其大小都是由 content + padding + border 决定的,但是盒子内容宽/高度(即 width/height)的计算范围根据盒模型的不同会有所不同:

标准盒模型:只包含 content 。
IE(替代)盒模型:content + padding + border 。

可以通过 box-sizing 来改变元素的盒模型:

box-sizing: content-box :标准盒模型(默认值)。
box-sizing: border-box :IE(替代)盒模型。
展开
评论
#每天一个知识点#
script 标签中 defer 和 async 的区别?

script :会阻碍 HTML 解析,只有下载好并执行完脚本才会继续解析 HTML。
async script :解析 HTML 过程中进行脚本的异步下载,下载成功立马执行,有可能会阻断 HTML 的解析。
defer script:完全不会阻碍 HTML 的解析,解析完成之后再按照顺序执行脚本。
展开
评论
#每天一个知识点#
如何理解 HTML 语义化?
让人更容易读懂(增加代码可读性)。
让搜索引擎更容易读懂,有助于爬虫抓取更多的有效信息,爬虫依赖于标签来确定上下文和各个关键字的权重(SEO)。
在没有 CSS 样式下,页面也能呈现出很好地内容结构、代码结构。
展开
评论
#每日一题# 🦶✍🏻️数组map
Array.prototype._map = function(fn) {
if (typeof fn !== "function") {
throw Error('参数必须是一个函数');
}
const res = [];
for (let i = 0, len = this.length; i < len; i++) {
res.push(fn(this[i]));
}
return res;
}
展开
评论
#每日一题# 🦶✍🏻️数组filter
Array.prototype._filter = function(fn) {
if (typeof fn !== "function") {
throw Error('参数必须是一个函数');
}
const res = [];
for (let i = 0, len = this.length; i < len; i++) {
fn(this[i]) && res.push(this[i]);
}
return res;
}
展开
评论
#每日一题# 🦶✍🏻️数组flat方法
function _flat(arr, depth) {
if(!Array.isArray(arr) || depth <= 0) {
return arr;
}
return arr.reduce((prev, cur) => {
if (Array.isArray(cur)) {
return prev.concat(_flat(cur, depth - 1))
} else {
return prev.concat(cur);
}
}, []);
}
展开
评论
下一页