JS

vue双向绑定
vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,
在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。

闭包
闭包是指有权访问另外一个函数作用域中的变量的函数。
闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。闭包就是就是函数的“堆栈”在函数返回后并不释放,
我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配。当在一个函数内定义另外一个函数就会产生闭包。

异步
异步执行的运行机制如下。
1、所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
2、主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
3、一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,
于是结束等待状态,进入执行栈,开始执行。
4、主线程不断重复上面的第三步。

CDN
CDN就是根据用户位置分配最近的资源

防抖节流区别
节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

跨域
如何解决跨域问题?
JSONP:通过动态创建script,再请求一个带参网址实现跨域通信。
document.domain + iframe跨域:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
location.hash + iframe跨域:a欲与b跨域相互通信,通过中间页c来实现。
三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。
window.name + iframe跨域:通过iframe的src属性由外域转向本地域,
跨域数据即由iframe的window.name从外域传递到本地域。
postMessage跨域:可以跨域操作的window属性之一。
CORS:服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求,前后端都需要设置。

1、JSONP,全称为json with padding,解决老版本浏览器跨域数据访问问题,
原理是web页面调用JS文件不受浏览器同源策略限制,
所以通过script标签可以进行跨域请求,流程如下:
首先前端设置好回调参数,并将其作为URL的参数
服务器端收到请求后,通过该参数获取到回调函数名,并将数据放在参数中返回
收到结果后因为是script标签,所以浏览器当做脚本运行,

2、cors,全称是跨域资源共享,允许浏览器向跨源服务器发出XMLHTTP Request请求,从而克服了ajax只能同源使用的策略,
实现cors的关键是服务器,只要服务器实现了cros接口,就可以跨域通信
前端逻辑很简单,正常发起ajax请求即可,成功的关键在于服务器 Access-Control-Allow-Origin 是否包含请求页面的域名,
如果不包含的话,浏览器将认为这是一次失败的异步请求,将会调用 xhr.onerror 中的函数。
Cros使用简单,支持POST方式,但是存在兼容问题
浏览器将cors请求分为两类,简单请求和非简单请求,对于简单请求,浏览器直接发出cors请求,就是在头信息之中增加一个origin字段,
用于说明本次请求来自哪个协议+域名+端口,服务器根据这个值,决定是否同意本次请求,
如果服务器同意本次请求,返回的响应中会多出几个头信息字段:
Access-Control-Allow-Orign:返回origin的字段或者*
Access-Control-Allow-Credentials,该字段可选,是一个bool值,表示是否允许发送cookie,
Access-Control-Expose-Headers

vue3与vue2区别
defineproperty api缺点
检测不到对象属性的添加和删除
数组API方法无法监听到
需要对每个属性进行遍历监听,如果嵌套对象,需要深层监听,造成性能问题

Proxy直接可以劫持整个对象,并返回一个新对象,我们可以只操作新的对象达到响应式目的
Proxy可以直接监听数组的变化(push、shift、splice)

强缓存:浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK
协商缓存: 向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,
如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;

箭头函数可以作为构造函数来使用吗?
构造函数是通过new关键字来生成对象实例,生成对象实例的过程也是通过构造函数给实例绑定this的过程,
而箭头函数没有自己的this。创建对象过程,new 首先会创建一个空对象,
并将这个空对象的proto指向构造函数的prototype,
从而继承原型上的方法,但是箭头函数没有prototype。因此不能使用箭头作为构造函数,也就不能通过new操作符来调用箭头函数。

箭头函数和普通函数有什么区别
1:写法不一样
2:普通函数存在变量提升的现象
3:箭头函数不能作为构造函数使用
4:两者this的指向不同
5:箭头函数的arguments指向它的父级函数所在作用域的arguments
6:箭头函数没有new.target

new一个对象背后做了些什么?
创建一个空对象
将所创建对象的proto属性值设为构造函数的prototype的属性值
执行构造函数中的代码,构造函数中的this指向该对象
返回对象

---------JSONP的缺点:
1.首先,它没有关于JSONP调用的错误处理,一旦回调函数调用失败,浏览器会以静默失败的方式处理。
2.其次,它只支持GET请求,这是由于该技术本身的特性所决定的。因此,对于一些需要对安全性有要求的跨域请求,
JSONP的使用需要谨慎一点了。
3.JSONP不支持用async:false的方法设置同步

从 URL 输入到页面展现到底发生什么?
DNS 解析:将域名解析成 IP 地址
TCP 连接:TCP 三次握手
发送 HTTP 请求
服务器处理请求并返回 HTTP 报文
浏览器解析渲染页面
根据 HTML 解析出 DOM 树
根据 CSS 解析生成 CSS 规则树
结合 DOM 树和 CSS 规则树,生成渲染树
根据渲染树计算每一个节点的信息
根据计算好的信息绘制页面
断开连接:TCP 四次挥手

三次握手
第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN(c),此时客户端处于 SYN_SENT 状态
第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,
为了确认客户端的 SYN,将客户端的 ISN+1作为ACK的值,此时服务器处于 SYN_RCVD 的状态
第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,值为服务器的ISN+1。
此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接

为什么不是两次握手?
如果是两次握手,发送端可以确定自己发送的信息能对方能收到,
也能确定对方发的包自己能收到,但接收端只能确定对方发的包自己能收到 无法确定自己发的包对方能收到

四次挥手
第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态,
停止发送数据,等待服务端的确认
第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1
作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态
第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,
发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,
且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,
此时客户端处于 TIME_WAIT状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,
服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态

四次挥手原因
服务端在收到客户端断开连接Fin报文后,并不会立即关闭连接,而是先发送一个ACK包先告诉客户端收到关闭连接的请求,
只有当服务器的所有报文发送完毕之后,才发送FIN报文断开连接,因此需要四次挥手

CDN
资源上传cdn之后,当用户访问cdn的资源地址之后会经历下面的步骤:

首先经过本地的dns解析,请求cname指向的那台cdn专用的dns服务器。
dns服务器返回全局负载均衡的服务器ip给用户
用户请求全局负载均衡服务器,服务器根据ip返回所在区域的负载均衡服务器ip给用户
用户请求区域负载均衡服务器,负载均衡服务器根据用户ip选择距离近的,并且存在用户所需内容的,
负载比较合适的一台缓存服务器ip给用户。当没有对应内容的时候,会去上一级缓存服务器去找,
直到找到资源所在的源站服务器,并且缓存在缓存服务器中。用户下一次在请求该资源,就可以就近拿缓存了

GET POST区别

GET

GET方法请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据

POST

POST方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用
本质上都是TCP链接,并无差别
但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中会体现出一些区别
get参数通过url传递,post放在request body中。
get请求在url中传递的参数是有长度限制的,而post没有。
get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。
get请求只能进行url编码,而post支持多种编码方式
get请求会浏览器主动cache,而post支持多种编码方式。
get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。

event loop
过程:
同步代码,一行一行放在call stack执行
遇到异步,会先"记录"下,等待时机(定时、网络请求等)
时机到了,就移动到callback queue
如call stack为空(即同步代码执行完)event loop开始工作
轮询查找callback queue,如有则移动到call stack执行
然后继续轮询查找(永动机一样)

浏览器存储
1.cookie
本身用于浏览器和server通讯
被"借用"到本地存储来
可用document.cookie = '...'来修改

cookie缺点
1.存储大小,最大4KB
2.http请求时需要发送到服务端,增加请求数据量
3.只能用document.cookie = '...'来修改

2.localStorage与sessionStorage
localStorage数据永久存储,除非手动删除
sessionStorage数据只存在于当前会话,浏览器关闭则清空

原型与原型链:
1.每个class都有显示原型的prototype
2.每个实例都有隐式原型proto
3.实例的proto指向对应class的prototype

作用域和作用域链
全局作用域:在任何地方都能被访问,window对象下的内置属性都是全局作用域
函数作用域:固定代码片段中
作用域链:作用域都有上下级关系,上下级关系确定函数在哪个作用域下创建,变量取值都会在当前作用域中查找,
如果没有查到就会像上级作用域查找,直到查到全局作用域,这个查找的过程叫做作用域链

网页突然加载不出来了
1.网络断开了
2.后端页面无法加载
3.网页被劫持了
4.DNS无法解析网址
5.服务器负载过大
6.供应商网络出口出现问题

git指令
git init 初始化仓库,默认为 master 分支
git add . 提交全部文件修改到缓存区
git add <具体某个文件路径+全名> 提交某些文件到缓存区
git diff 查看当前代码 add后,会 add 哪些内容
git diff --staged查看现在 commit 提交后,会提交哪些内容
git status 查看当前分支状态
git pull <远程仓库名> <远程分支名> 拉取远程仓库的分支与本地当前分支合并
git pull <远程仓库名> <远程分支名>:<本地分支名> 拉取远程仓库的分支与本地某个分支合并
git commit -m "<注释>" 提交代码到本地仓库,并写提交注释
git commit -v 提交时显示所有diff信息
git commit --amend [file1] [file2] 重做上一次commit,并包括指定文件的新变化
git branch 查看本地所有分支
git branch -r 查看远程所有分支
git branch -a 查看本地和远程所有分支
git merge <分支名> 合并分支
git merge --abort 合并分支出现冲突时,取消合并,一切回到合并前的状态
git branch <新分支名> 基于当前分支,新建一个分支
git checkout --orphan <新分支名> 新建一个空分支(会保留之前分支的所有文件)
git branch -D <分支名> 删除本地某个分支
git push <远程库名> :<分支名> 删除远程某个分支
git branch <新分支名称> <提交ID> 从提交历史恢复某个删掉的某个分支
git branch -m <原分支名> <新分支名> 分支更名
git checkout <分支名> 切换到本地某个分支
git checkout <远程库名>/<分支名> 切换到线上某个分支
git checkout -b <新分支名> 把基于当前分支新建分支,并切换为这个分支

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容