学习记录无数问(js篇)

一: 什么是防抖和节流?有什么区别?

防抖: 触发高频事件n秒后函数只会执行一次,但在n秒内高频事件如果再次触发,则重新计时(一般在input获取输入值之类的会使用到)

节流:高频事件触发在n秒内,无论触发多少次,都只执行一次(一般用在用户获取验证码,滚动请求数据之类会使用到, 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每n秒发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。)

二:JS 异步解决方案的发展历程以及优缺点?

  1. 回调函数(callback)
    优点:解决了同步的问题(只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。)
    缺点:回调地狱,不能用 try catch 捕获错误,不能 return
setTimeout(() => {
    // callback 函数体
}, 1000)

2.Promise
优点:解决了回调地狱的问题
缺点:无法取消 Promise ,错误需要通过回调函数来捕获

  1. Generator
    优点:可以控制函数的执行

  2. Async/await
    优点是:代码清晰,不用像 Promise 写一大堆 then 链,处理了回调地狱的问题
    缺点:await 将异步代码改造成同步代码,如果多个异步操作没有依赖性而使用 await 会导致性能上的降低。

三:http2 的多路复用?

1.HTTP2采用二进制格式传输,取代了HTTP1.x的文本格式,二进制格式解析更高效。同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接而带来的延时和内存消耗。

2.在 HTTP/2 中,有两个非常重要的概念,分别是帧(frame)和流(stream)。
帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。
多路复用,就是在一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极大的提高传输性能。

四: TCP 三次握手和四次挥手的理解?

TCP三次握手:
1、客户端发送syn(在连接建立时用来同步序号)包到服务器,等待服务器确认接收。

2、服务器确认接收syn包并确认客户的syn,并发送回来一个syn+ack(TCP协议规定,只有ACK=1时有效)的包给客户端。

3、客户端确认接收服务器的syn+ack包,并向服务器发送确认包ack,二者相互建立联系后,完成tcp三次握手。
三次握手之所以是三次是保证client(客户端)和server(服务器)均让对方知道自己的接收和发送能力没问题而保证的最小次数。

四次挥手:
TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。。所以关闭双通道的时候就是这样:

客户端:我要关闭输入通道了。
服务端:稍等,还有一些数据给你
服务端:好了,我也要关闭输入通道了。
客户端:好的你关闭吧,我也把这个通道关闭。

五: HTTP和 HTTPS有什么区别?

1.HTTP(超文本传输协议):
是一个应用层协议,由请求和响应构成,基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等),HTTP默认的端口号为80,明文传输,连接简单,但是不安全,容易造成信息泄露

2.HTTPS(超文本传输安全协议):
HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。默认端口号为443,需要到CA申请证书,不免费的
详情:https://juejin.cn/post/6844903599303032845

六:浏览器输入URL发生了什么?

1.当用户按下回车键,浏览器开始检查URL是否符合规范,然后组装协议,构成完整的URL

2.浏览器进程通过进程间通信(IPC)把url请求发送给网络进程,检查是否有本地缓存该请求资源,如果有,则返回给浏览器进程,

3.没有则向web服务器发送HTTP请求,过程:
-进行DNS解析,获取服务器IP地址和端口号;
-通过IP地址和服务器建立TCP连接;
-构建请求头,发送请求头;
-服务器响应后,网络进程接收响应头和响应信息,并解析响应内容;

4.网络进程解析响应流程:
-检查状态码,-200状态码:检查响应类型Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行,后续的渲染,如果是html则通知浏览器进程准备渲染进程准备进行渲染。
在这里插入图片描述

5.浏览器进程检查当前url是否和之前打开的渲染进程根域名是否相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程

6.渲染进程准备好后,接收完整数据,向浏览器发送“确认提交”,浏览器进程接收到确认消息后更新浏览器界面状态:安全、地址栏url、前进后退的历史状态、更新web页面。
详情:https://time.geekbang.org/column/article/117637

七:GET与POST的区别?

1.GET:传参方式是通过URL地址栏传参,请求数据放在URL?后面,通过&符号进行参数分割,传递的参数是可见的,对传递数据大小有限制,最大2048字符.回退不会影响,请求可以被缓存,请求记录会被保存在历史记录中.

2.POST:传参方式URL不可见,数据存放在HTTP包体内,数据大小是没有限制的,回退会重新提交,数据不能被缓存,请求也不会有历史记录.

八:浏览器请求跨域?

https://blog.csdn.net/ashleyjun/article/details/98849400
url构成: 协议://服务 域名( IP:端口)/URI?key1=value1&key2=value2#xxxx;
协议:http、https、ftp…
服务:万维网(World Wide Web )
域名 = 标识串(baidu 、google、sina…)+网站类型(com、gov、edu…)
端口号:以数字形式表示,若协议为HTTP,默认端口号为80,可省略不写,https为443;
查询:以“?”为起点,每个参数以“&”隔开,以“=”分开参数名称与数据
片段:以“#”字符开头

跨域: 就是相对同源策略而言,域名,端口号,协议都相同就是同源,否则就是跨域;

解决一: JSONP, 让网页从跨域地址那获取资料,及跨越数据;
原理: 一个HTML中可以有多个script标签,数据间可以互相访问,src不仅能导入本地资源,也能导入远程资源,src没有同源限制,所以可以跨域请求数据;

解决二: 服务器代理,浏览器有跨域限制,但是服务器不存在跨域问题,所以可以由服务器请求所要域的资源再返回给客户端。
https://zhuanlan.zhihu.com/p/81809258

九:js单线程运行的宏任务,微任务,eventLoop?

eventLoop:是解决JS单线程运行阻塞的一种机制,在JS的异步运行机制中,我们需要知道:
1.所有的「同步任务」都在主线程进行,
2.「异步任务」进入任务队列,任务队列会通知主线程,哪个异步任务可以执行,这个异步任务就会进入主线程。异步任务必须指定回调函数,当主线程开始执行异步任务,其实就是在执行对应的回调函数。
3.如果主线程的所有同步任务都执行完,系统就会去读取「任务队列」上的异步任务,如果有可以执行的,就会结束等待状态,进入主线程,开始执行。
4.主线程不断的执行第3步
这就是JS的运行机制,也称为「Event Loop」事件循环。

1.宏任务(macrotask):创建主文档对象,解析HTML,执行主线或全局js代码,及更改url各种事件,属于宏任务的事件有:script(整体代码)、setTimeout、setInterval、setImmediate、I/O、UI rendering.

2.微任务(microtasks):更新程序状态,但是必须在浏览器任务继续执行其他任务前执行的任务,简言之就是代码自上而下执行,在开始新一轮宏任务前,必须执行完微任务才能开始新一轮的宏任务,微任务事件:Promise.then,catch,finally,object.observe等.

3.Promise是立即执行函数,是个同步函数也就是在宏任务里执行,Promise后面的.then是微任务(.then里面有Promise也是立即执行,比此轮宏任务的setTimeout函数还先执行的那种立即执行,因为代码执行到setTimeout时只是将事件放入任务列表,得下轮任务开始才执行; .then后面跟着的.then是放进微任务栈中,立即执行,因为本质返回的是个Promise)

console.log('1')

setTimeout(() => {
  console.log('2')
}, 0)

Promise.resolve().then(() => {
  console.log('3')
}).then(() => {
  console.log('4')
})

console.log('5')
//运行结果
//1
//5
//3
//4
//2

过程分析:
1、任务队列中只有script,则将script中所有函数放进函数执行栈按顺序执行

2、接下来遇到setTimeout,这里的setTimeout只是将回调函数在0毫秒后放入任务队列(其实是4ms,html5标准中规定中要求setTimeout中低于4ms的时间间隔算为4ms),也就是说回调函数在下一个事件循环执行,setTimeout在这里将回调函数放至任务列表后就结束了(ps:下一轮宏任务开始才执行)。

3、遇到Promise,.then属于「microtasks」,所以将第一个then的回调放到microtasks队列

4、执行完所有script代码后,检查microtasks队列,发现队列不为空,所以执行第一个回调函数输出’3’,由于then的返回仍然是Promise,因此将第二个then的回调放至microtasks队列并执行输出’4’。

5、此时microtasks队列为空,开始执行下一个事件循环。检查task队列发现setTimeout的回调函数,因此执行输出’setTimeout’

十: js深拷贝与浅拷贝?

基本数据类型: String,Number,Null,Undefined,Symbol,Boolean;
1.它们保存在栈内存内,因为栈比堆速度快,基本数据类型比较稳定相对占用内存小;
2.可以使用typeof可以检测基本数据类型是什么,但null返回的是Object,因此null表示的是空对象的指针,undefined是null的衍生,所以 undefined==null // true;

引用数据类型:Object(包括Array,Date,RegExp,Function);
1.引用类型是动态的,保存在堆内存中(只是在栈内存了一个对象的引用或者说是指针),因为堆比栈更大,放栈内存中会降低查找速度;
2.堆内存是无序的,可根据引用(指针)直接获取;
3.引用类型检查数据类型用 instanceof ,使用typeof都是返回object

深浅拷贝只针对引用类型(ps:其实基本数据类型改变值算深拷贝,因为改变不会影响原来的值)

  1. 浅拷贝: 只复制指向对象的指针,不复制本身,新旧对象共享同一内存,所以修改新对象会改变旧对象的值;

2.深拷贝:创建一个一模一样的对象,不共享内存,所以修改新对象不会改变旧对象的值;

js自带深拷贝的方法:
array: slice()、concat、Array.from()、… 操作符:只能实现一维数组的深拷贝;
Object: Object.assign():只能实现一维对象的深拷贝;JSON.parse(JSON.stringify(obj)):可实现多维对象的深拷贝,但会忽略undefined、任意的函数、symbol 值;
FUnction: bind(),eval, new Function(ary1,ary2…,function-body) // 需将参数与函数体提取出来;
(JS 提供的自有方法并不能彻底解决Array、Object的深拷贝,只能自己实现)

十一: 原型链?

(–proto–中划线其实为两条下划线,markDown无法转义只能这样写)

原型: 构造函数的 prototype 指向原型对象(只有函数有prototype,对象没有),原型对象有一个 constructor 属性指回构造函数,每个构造函数生成的实例对象都有一个 --proto-- 属性,这个属性指向创建那个构造函数的原型对象。isprototypeof()方法可以确定对象间是否有关系.
原型链: 简单理解就是原型组成的链,当需读取某个对象的属性时,首先会从对象实例本身开始,如果实例中找到该属性则返回值,没有则继续通过–proto–向上搜索指向的构造函数,没有则通过prototype搜索指向的原型对象,层层递进(原型对象的__proto__属性指向null); 假如我们让原型对象(A)等于另一个类型的实例呢?此时原型对象将包含另一个原型(B)的指针,相应的B中也包含着指向自己构造函数的指针(constructor),可以向下访问,这就构成了实例与原型的链条.在这里插入图片描述
![image.png](https://img-blog.csdnimg.cn/img_convert/4086ff95ea5c144e89a031538917298f.png

function pig(name) {this.name=name}  //pig的构造函数
let sonPig=new pig('lucy')  //pig的实例

pig.prototype===sonPig.__proto__  //  true 

pig.__proto__===Function.prototype// true

pig.prototype.constructor===pig // true

pig.prototype.isPrototypeOf(sonPig) //true

https://blog.csdn.net/u012468376/article/details/53121081;
https://zhuanlan.zhihu.com/p/62903507

十二: new 一个对象的过程?

1.创建一个空对象;
2.让构造函数的this指向新对象;
3.设置新对象的–proto–属性指向构造函数的原型对象;
4.判断返回数据类型,如果是值类型,返回新对象,是引用类型则返回这个引用类型的对象.

十三: 组件,模块化编程?

组件: 将js,HTML,css包装在一起,提供方法和效果;
模块化: 将相同功能抽取出来,存放在一个位置进行编程;

十四: let 与const?

  1. 不存在变量提升,须在声明后使用,否则会报错;
  2. 存在暂时性死区,区块作用域内存在let,const命令,这个区块对这些命令声明的变量是形成封闭作用域,凡在声明前使用就会报错,无论作用域外是否有同名变量;
  3. 不允许相同作用域内重复声明一个变量,会报错;
//{ }->这叫块级作用域,ES6允许块级作用域任意嵌套;
    {{
        let a="hello"
        console.log(a) //hello
    }}

   {
        {let a="hello"}
        console.log(a) //Uncaught ReferenceError: a is not defined (因为没有变量提升,外层作用域无法读取内层变量)
    }

十五: 下面的代码打印什么内容,为什么?

let b = 10;
(function b(){
    b = 20;
    console.log(b); 
})();

打印结果内容如下:

ƒ b() {
b = 20;
console.log(b)
}

原因:
作用域:执行上下文中包含作用域链:
在理解作用域链之前,先介绍一下作用域,作用域可以理解为执行上下文中申明的变量和作用的范围;包括块级作用域/函数作用域;
特性:声明提前:一个声明在函数体内都是可见的,函数声明优先于变量声明;
在非匿名自执行函数中,函数变量为只读状态无法修改;js作用域中先从最近的开始向上寻找,b=20没有被声明,所以在非严格模式下打印出函数体.

十六: 实现一个sleep函数,从Promis,Async/Await 等角度实现?

   //Promise:
    function sleep(time) {
        return new Promise((resolve => setTimeout(resolve, time)))
    }

    sleep(1000).then(() => {
        console.log("睡了一觉啦~")
    })

    //Async/Await :
    function sleep(time) {
        return new Promise(resolve => setTimeout(resolve, time))
    }

    async function res() {
        await sleep(1000)
        console.log("我睡了一觉啦~")
    }

    res()

十七: Cookie、SessionStorage、LocalStorage区别?

Cookie: 主要用来判断用户是否登录,默认是关闭浏览器后失效, 但是也可以设置过期时间,每次请求都会携带在HTTP请求头中,如果使用cookie保存过多数据会带来性能问题;

localStorage: 主要用于本地储存,长期存储数据,比如:购物车,浏览器关闭后数据不丢失;

sessionStorage: 主要用于会话存储,数据在浏览器关闭后自动删除。

Cookie容量限制: 大小(4KB左右)和个数(20~50);
SessionStorage和LocalStorage容量限制: 大小(5M左右)

十八: js 中强制转型?

在js中两个参数的内置类型间的转换被称为强制转型;
显示强制转换: parseInt,parseFloat,Number;
隐式强制转换: == ===

//显式强制转换:
   let a = "123"
   let b = Number(a)
   console.log(a, b, typeof a, typeof b)  // 123 123 string number
   
//隐式强制转换:
    let a="123"
    let b=a*1  //这样a的值"123"会被隐式转换成123
    console.log(a, b, typeof a, typeof b)  //123 123 string number

十九: undefined 和 not defined的区别?

    let a;  //声明了一个变量a,但未被赋值
    console.log(a)   //undefined
    console.log(c)  // 试图使用一个不存在且尚未声明的变量,js抛出错误“c is not defined”

二十: undefined 和 null 的区别?

undefiend: 已经声明,尚未被初始化;
null: 空值,表示 “什么都没有”,是一个只有一个值的特殊类型,表示一个空对象引用;

null 和 undefined 的值相等,但类型不等:

typeof undefined             // undefined (typeof 一个没有值的变量会返回 undefined)
typeof null                  // object
null === undefined           // false
null == undefined            // true

二十一: Vue 的SPA单页面的优缺点?

优点: 用户体验好,快,切换页面不用重新加载整个页面,避免了不必要的跳转和渲染;相对服务器压力较小,前后端分工明确,架构清晰,前端负责逻辑交互,后端负责数据处理;

缺点:

初次加载耗时多: 因为需要将html,js,css统一进行加载,只有部分页面按需加载;
前进后退路由需自己建立堆栈管理,因为不能使用浏览器自带的前进后退功能;
SEO难度较大: 因为所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。
如何解决:
1.首屏加载时间过长: 加载过多的问题可以通过webpack优化 ,尽可能减少加载项,或者预渲染 prerendering(适用于静态站点),但终极方案还是ssr(适合动态渲染,但配置繁琐,Nuxt可以帮助简化配置),

路由用vue-router进行管理

如何SEO(搜索引擎优化): 1. 内容建设:是不是当前广大用户需求的内容?2. 竞争对手:对手都是怎么在做的?我们如何差异化3. 协调资源:我们该协调那些资源来促成这次seo修改?4. 站内优化:把你的seo细节做到极致5. 站外优化:网站上线,如何推广、链接建设促进收录和排名6. 迭代优化:数据分析促进页面体验的不断完善修改
https://www.zhihu.com/question/19760381/answer/21614135

二十二: 加法操作?

    let a = true
    console.log(true==1,false==0)     // true  true
    console.log(a + true)       // 2
    console.log(a + false)      // 1
    console.log(a + 1)         // 2
    console.log(a + "bcd")     // truebcd

所以不同类型执行加法操作是这样的:
Number + Number 执行加法; (例: 2 +2 = 4)
Boolean + Number 执行加法; (例: true + 2 = 3)
Boolean + Boolean 执行加法; (例: true + true = 2)
Number + String 执行连接; (例: 2 + “abc” = “2abc” ; 2 + “2” = “22”)
String + Boolean 执行连接; (例:“2” + true = “2true”)
String + String 执行连接; (例: “2” + “2” = “22”)

二十三: webSoket的原理及其运用?

webSoket: 是一种网络通信协议, 在单个TCP连接上进行的全双工传输协议,服务端可以主动向客户端发送数据,标识符是WS(如果加密则为wss),一般可用实时聊天,(以往使用轮询的方式,需要不停发送ajax请求,浪费服务器资源)
http://www.ruanyifeng.com/blog/2017/05/websocket.html
在这里插入图片描述

1 建立在 TCP 协议之上,服务器端的实现比较容易。
2.与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手 时不容易屏蔽,能通过各种 HTTP 代理服务器。
3.数据格式比较轻量,性能开销小,通信高效。
4.可以发送文本,也可以发送二进制数据。
5.没有同源限制,客户端可以与任意服务器通信。
6.协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值