您的位置:首页 > Web前端 > JavaScript

二、开发过程中遇到的js知识点总结(2)

2021-04-20 11:01 405 查看

1.虚拟DOM优点

  减少DOM操作

    虚拟DOM可以将多次操作合并为一次操作,比如你添加1000个节点,是一个一个操作的(减少DOM操作的次数)

    虚拟DOM借助DOM diff 可以把多余的操作省掉,比如你添加1000个节点,其实只有10个是新增的(减少DOM操作的范围)

    其实就是DOM操作会操作1000次,虚拟DOM只会操作一次

  跨平台

    虚拟DOM不仅可以变成DOM,还可以变成小程序、ios应用、安装应用,因为虚拟DOM本质上只是一个JS对象

2.缺点

  需要额外的创建函数,如vue中的 h ,但可以通过js简化写法(jsx的缺点,严重依赖打包工具)

 

diff算法有个缺点,在vue中加上key就可以了,key是有默认值的,就是当前的index,所以不能使用key作为index

闭包

(function fout {
let const a = 1;
function fin(){
console.log(a)
}
})()()
// 1
// 第一个 () 表示立即执行函数 fout 得到 fin 函数,后面的 () 表示立即执行 fin

 

2.class

  

class p {
constructor() {
this.name = 'zhangning';
this.age = '24';
}

say() {
console.log('会说话')
}
}

class zn extends p {
// 复杂写法
/*constructor(){
super();// 必须。就是调用父类的 constructor
this.name = 'ningning';
}*/
// 简单写法,不用调用 super() ,默认自动调用
name = 'ningning';

play() {
console.log('喜欢运动');
}
}

 

3. async await 

// 可以省略掉 then 简单快捷
async function a () {
let res = await axios();// 这里会等待成功 才会执行下面
console.log(res);
}

  async 函数是什么? 

    它就是 Generator 函数的语法糖,

    async + await 原理就是 generate + yield 的语法糖

    async + await 其实就是 generate + yield 的写法

  为什么要有 async await? 

    因为方便,看起来代码清晰

 

4.事件循环

// 宏任务 定时器  微任务  promise
console.log(1);
setTimeout(() => {
console.log(2);
}, 0)
// 注意 new Promise 是立即执行的, 而 .then 操作是需要异步执行的
new Promise(resolve => {
console.log(3);
resolve();
}).then(() => {
console.log(4);
})
// 1 3 4 2

 

  宏任务、微任务

    MacroTask(宏任务):setTimeout setInterval ...

    MicroTask(微任务):process.nextTick、Promise、Object.observe、MutaitionObserver

  先执行同步任务,再取出第一个宏任务执行,所有的相关微任务总会在下一个宏任务之前全部执行完毕,先微后宏

  js代码执行机制

    所有同步任务都在主线程上的栈中执行

    主线程之外还存在一个任务队列(task queue)。只要异步任务有了运行结果,就在任务队列之中放置一个事件

    一旦 栈 中的所有同步任务执行完毕,系统就会读取 任务队列 ,选择出需要首先执行的任务(由浏览器决定)

 5.vue配置history模式,刷新404,就需要服务器配置路由重写,指向 index.html 才可以

 

6.一次完整的HTTP服务过程

  当我们在web浏览器的地址栏中输入 www.baidu.com 具体发生了什么?

    1.对 www.baidu.com 这个网址进行DNS域名解析,得到对应的ip地址

    2.根据这个ip地址,找到对应的服务器,发起 TCP 的三次握手

    3.建立 TCP 连接后发起 HTTP 请求

    4.服务器相应 HTTP 请求,浏览器得到 html 代码

    5.浏览器解析 html 代码,并请求html代码中的资源(js、css、图片等)(先得到html代码,才能去找这些资源)

    6.浏览器对页面进行渲染呈现给用户

    7.服务器关闭,关闭 TCP 连接

  http 协议是请求与响应模式,也就是说一般情况下,是客户端主动发起请求而服务器响应客户发送的请求,如果服务器主动给客户端发送消息需要利用长连接。

  http协议的请求分为三部分,get请求是没有 body 的,而是url拼接的方式传递。

    请求报文

      1.起始行  2.报文头  3.报文体

    响应报文

      1.起始行  3.响应头  3.响应体

    起始行包括 请求方式(GET/POST)、请求URL、与协议版本

    头部段 包括 hander值一般用于传递公共参数 键值对的方式

    body 包括接口返回的数据,或者 POST 请求入参的参数

  http 返回状态码

    1xx 处理信息,代表服务器已经收到请求,需要你继续执行操作

    2xx 代表请求成功,操作从成功被服务器接受并处理

    3xx 重定向需要进一步操作已完成请求

    4xx 客户端错误,请求包含语法错误或无法完成请求

    5xx 服务器错误,服务器在处理请求的过程中发生了错误

  http协议栈

    第一层 http协议

    第二层 TCP传输层

    第三层 IP层

    第四层 数据链路层

    第五层 物理层

  https 以安全为目标的 http 通道,在http基础上通过传输加密和身份认证保证了传输过程的安全性。https在http的基础下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。HTTPS存在不同于HTTP的默认端口及一个加密、身份验证层(在HTTP与TCP之间)。这个系统提供了身份验证与加密通讯方法。

   http 协议是不安全的,在数据传输的过程中都是明文,所以可能存在数据泄露和篡改
    可以使用对称密钥进行数据加密。对称密钥分别交给客户端和服务端,他们之间传输的数据都是用对称密钥进行加密和解密。

  

 

7.xss和csrf是什么

  xss(Cross Site Script:中文是跨站脚本攻击)

    XSS 攻击是指攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。

    XSS 攻击分为三种类型:反射性(非持久型)、存储型(持久型)、基于DOM

   解决方法:记住两点 过滤输入、转义输出

    具体执行的方式有以下几点:
    第一、在输入方面对所有用户提交内容进行可靠的输入验证,提交内容包括URL、查询关键字、http头、post数据等

    第二、在输出方面,在用户输内容中使用标签。标签内的内容不会解释,直接显示。

    第三、严格执行字符输入的字数控制

    第四、在脚本执行区中,应绝无用户输入

  CSRF/XSRF:跨站请求伪造。

    可以这么理解 CSRF 攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF 能够做的事情包括:以你的名义发送邮件、发消息、盗取你的账号、甚至于购买商品、个人隐私泄露以及财产安全。

   解决方式:

    1.只是用JSON API

      使用js发起AJAX请求是限制跨域的,并不能通过简单的表单来发送 JSON ,所以通过只接收JSON可能很大避免CSRF攻击

    2.验证 HTTP Referer字段

      根据 HTTP 协议,在HTTP头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址,在通常情况下,访问一个安全受限页面的请求来自于同一个网站

    3.在请求地址中添加takon验证

      CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于cookie中,因此黑客可以在不知道这些验证信息的情况下直接利用自己的 cookie 来通过安全认证。要防御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的token,并在服务器端建立一个拦截器来验证这个token。这种方法比检查 Referer 要安全一些。

 

8. Event Loop

  Event Loop  即事件循环,是指浏览器或 Node 的一种解决 javaScript 单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。

  堆(Heap)

    堆 是一种数据结构,是利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆,将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

    堆是线性数据结构,相当于一堆数组,有唯一后继。

  栈(Stack)

    栈在计算机中是限定仅在表尾进行插入或删除操作的线性表。栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。

    栈是只能在某一端插入和删除的特殊线性表。

  队列(Queue)

    特殊之处在于它只允许在表的前端(frout)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。

    进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

    队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队,因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出。

 

  在 JavaScript 中,任务被分为两种,一种宏任务(MacroTask) 也叫 Task,一种叫微任务(MicroTask)

  宏任务:js全部代码、setTimeout、setInterval、I/O、UI Rendering

  微任务:Process.nextTick(Node独有)、Promise、MutationObserver

 

9.什么是浏览器缓存(强缓存,协商缓存)

  当浏览器访问过后的资源,会被浏览器缓存在本地,当下次在访问页面的时候,如果没有过期,直接读取缓存,加快浏览器的加载效率。

  http 缓存机制:

    1.Expires:通过设置最大缓存时间,当时间超过就去服务器下载。

    2.http1.1 cache-control: max-age = time,当time过期后,检测 etag 带上 etag往服务器发请求,如果 etag 没变,直接高度浏览器读本地缓存,如果没有 etag 就会检测 last-Modified,判断 如果上一次更改的时候,距离本次访问时间比较久,说明文件没有发生改变,返回304.

  强缓存就是当前访问时间还在设置的最大时间范围内。

  协商缓存就是时间过了,通过检查 etag 或者 last-modifed 来使用缓存的机制

   etag: 每个文件有一个,改动文件了就变了,就是个文件hash,每个文件唯一,就像用webpack打包的时候,每个资源都会有这个东西,如: app.js打包后变为 app.c20abbde.js,加个唯一hash,也是为了解决缓存问题。

  last-modifed: 文件的修改时间,精确到秒      也就是说,每次请求返回来 response header 中的 etag和 last-modified,在下次请求时在 request header 就把这两个带上,服务端把你带过来的标识进行对比,然后判断资源是否更改了,如果更改就直接返回新的资源,和更新对应的response header的标识etag、last-modified。如果资源没有变,那就不变etag、last-modified,这时候对客户端来说,每次请求都是要进行协商缓存了

  发请求-->看资源是否过期-->过期-->请求服务器-->服务器对比资源是否真的过期-->没过期-->返回304状态码-->客户端用缓存的老资源。

  这就是一条完整的协商缓存的过程。

  当然,当服务端发现资源真的过期的时候,会走如下流程:

  发请求-->看资源是否过期-->过期-->请求服务器-->服务器对比资源是否真的过期-->过期-->返回200状态码-->客户端如第一次接收该资源一样,记下它的cache-control中的max-age、etag、last-modified等。

  所以协商缓存步骤总结:

  请求资源时,把用户本地该资源的 etag 同时带到服务端,服务端和最新资源做对比。
  如果资源没更改,返回304,浏览器读取本地缓存。
  如果资源有更改,返回200,返回最新的资源。

  怎么设置强缓存和协商缓存?
   1.后端配置
// 后端服务器如nodejs:
res.setHeader('max-age': '3600 public')
res.setHeader(etag: '5c20abbd-e2e8')
res.setHeader('last-modified': Mon, 24 Dec 2018 09:49:49 GMT)

  2.nginx 配置  

 

 

10.说一下浏览器垃圾回收机制

  老:标记清楚法,GC会检测当前对象有没有被变量所引用,如果没有就回收。

  新:Scavenge,把内存空间分为两部分,分别为 From 空间和 To 空间。当一个空间满了以后,会把空间中活动对象转移到另一个空间这样互换。

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: