底层原理
堆栈
浏览器渲染原理
1.css渲染
link
@import
style内嵌
2.js渲染
1.默认的script标签
2.默认的script src标签
3.defer和async
扩展:并发
js的运算顺序
成员访问优先级是大于赋值的
连等
var a = b =1,这个是先创建1这个常量,然后b=1,然后a=1,或者说a=b,其实结果都是一样的
var a =1,b=1;这个其实就是两个var,var a =1;var b=1;
优先级mdn
基于http网络协议层的优化(输入URL到看到页面,中间经历的环节)
1.URL解析
3.DNS解析
4.TCP三次握手
5.数据传输,基于传输协议
6.TCP四次挥手:断开TCP连接通道
性能优化汇总总结
1.优化总结
2.http2.0
检测数据类型的四种方式
1.typeof
2.instanceof<br>
3.constructor
4.Object.prototype.toString.call
事件
事件对象
阻止事件默认行为
href="javascript:;"
绑定事件的时候通过事件对象阻止
返回false
preventDefault
事件的传播机制(顺序执行)
1.捕获阶段
2.目标阶段
3.冒泡传播
阻止冒泡传播,ev.stopPropagation()
DOM2的事件绑定方法,第三个参数传true,就是说明在捕获阶段执行,用到的情况几乎没有,DOM0只能在目标阶段和冒泡阶段执行
图解
事件委托(事件代理)
onmouseover和onmouseenter的区别
跨域(非同源策略)
什么是跨域
产生的原因
1.前后端分离,不在一个服务器部署
2.为了保证服务器合理利用,有图片服务器,视频服务器,前端服务器,后端服务器
3.项目太大,需要子域名,比如v.qq.com lol.qq.com,lol官网调用腾讯视频的视频
解决的方法
1.最早的方案,在开发的时候,后端的代码也放到前端的电脑上,而且搭建后的环境,之后用wamp修改Host文件实现<br>
2.其他的方案,存在很短的时间
1.window.name
2.postMessage<br>
3.jsonp
4.CORS跨域资源共享<br>
5.webapck的proxy
6.nginx反向代理,真实生产环境用的
jquery
1.jquery的加载方式,暴露api,看看是否有Window,然后选择是commenjs方式还是esmoudle方式
2.jquery的使用时创建实例的方法,工厂模式
1.平时都是用new 创建实例,但是jquery直接$()就可以
2.其实使用的是创造一个干爹,内部new的是一个init的函数,里面没啥东西,但是把他的原型prototype指向jquery的prototype,所以就想一个干爹
3.平时$().each啥的函数都是在jquery的prototype上得
4.平时$.ajax的东西其实用的jquery的静态属性方法
3.jquery里面常用的数据类型检测的源码
4.jquery选择器
1.$() -> 返回的都是JQ类的实例(JQ对象) 「格式:空实例对象、类数组集合...」
2.[selector] 选择器支持的格式
3.把JQ对象(一般类数组集合) 转换为 原生DOM对象:可以调用浏览器提供的内置的属性和方法
4.优化点,如果不想链式调用,嫌不好看,可以这样
选择器实现的源码
5.each
Iterator迭代器和Generator生成器
Iterator<br>
含义
拥有next方法用于依次遍历数据结构的成员
每一次遍历返回的结果是一个对象 {done:false,value:xxx}
拥有Symbol.iterator属性的数据结构(值),也就是可以直接for of的
数组
部分类数组:arguments/NodeList/HTMLCollection...
String
Set
map
generator object
Iterator这个内置对象默认不具备Symbol.iterator,属于不可被遍历的数据结构
Symbol.iterator和Iterator内置类的实现源码
Generator
他不能被new,否则会报错,函数运行,就返回一个Generator实例
yield
每一次执行next,遇到yield会暂停函数的执行,value -> yield后面的值
return方法
执行next还可以传递值「第一次没必要,其余每次传递的值,都是给上一次yield的处理结果
yield如果返回一个Generator,想让他运行就加一个*
生成器函数虽然是个实例,但是其中的this不是其实例,而是window/undefined
面向对象
对象的细分
自定义对象
new一个函数
自己写一个new
object.create(),创建一个对象,让其原型链指向所传的属性,但是创建的对象没有constructer,也可以说是纯粹的对象
原型和原型链
完整图解
建议看笔记几道题
简易图解
原型重构
将原型对象直接赋值一个对象会造成的影响
1.丢失了constructor
2.原始内置原型对象的属性和方法也会丢失
解决方案
object.assign()
图解
用的很少,但也有这样用的
用的很少,但是有面试题
Function类和Object类的关系
万物接对象
Function.prototype === Function.__proto__ ===Object.__proto__
私有属性和公有属性的检测方法
hasOwnProperty检测是否为私有属性
hasPubProperty检测是否为公有属性(自己定义的,一层层递归向下找)
getPrototypeOf获取原型上的属性
new fun的优先级小于 new fun(),new fun()的优先级等于对象获取属性的优先级
创建基本数据类型值和引用数据类型值的时候是不同的
es6创建类和es5创建类
es6创建的fn只能被new,直接执行fn()会报错,图片里面有
JS中THIS的五种情况梳理
1.事件行为
2.普通函数执行
拓展hasOwnProperty和in<br>
3.构造函数执行
5.call/apply/bind可以改变函数中this的指向(强行改变)
同步异步
异步场景(浏览器端)
定时器
JS中的事件绑定
Ajax/Fetch请求的发送(HTTP事务)
Promise设计模式管控异步编程的(包括:async/await...)
异步操作的运行机制
微任务
promise(不是new Promise)
await<br>
genertor<br>
题
ajax的同步异步
AJAX的状态
异步过程
XHR.OPEN第三个参数控制的同步异步,true为异步
js打包模式
umd
主要是支持commonjs(node)后端和 amd规范(require.js定义的规范),常用工具打包是webpack,这样打包umd之后是直接在项目里面跑完之后在浏览器运行的
esm
这个打包之后是为es6准备,可以直接import啥的
分组件打包
这个就是打包成按需加载那种,具体得看项目代码
gulp
一般都是用来打包css样式,现在用的很少了
Promise
实例结构
promise.reject()返回一个错误状态的实例
promise.resolve()返回一个正确状态的实例
同步异步(then)
无定时器情况下,resolve和reject只是改变内部状态,改变是同步的
无定时器情况下,then里面的回调函数不会立即执行,而且放到eventqueue的微任务队列里面,等主进程结束再执行,所以是异步
有定时器情况下,先将定时器放到宏任务队列,then的时候,状态还是pending,定时器还没执行呢,所以不会执行then里面的回调函数,只是先存起来。等定时器结束之后,里面的resolve或者reject执行的时候,先同步状态,然后再讲then里的回调放到微任务队列,执行完定时器里面的其他主进程任务后,再执行微任务的回调函数
所以,可以说,promise是同步的(改变内部状态),只不过then的时候,或者resolve和reject执行的时候会出现异步
链式then
1.首先then这个方法会返回一个新的promise实例
2.不管执行的then里面失败的回调还是成功的回调,只要运行回调函数时不报错
1.运行回调函数时返回一个新的promise,那么这个新的promise就是下一个then运行的promise
2.运行回调返回一个值,就是说return一个新的值,那么下一个then就是运行成功的回调,参数就是return的值,如果没return值,那下一个then的成功回调的参数就是undefined
3.运行任何一个函数时报错了,下一个then就会运行失败的回调,参数是报错的原因
面试题(看不太懂),谁先知道可执行,就谁先执行
穿透性
1.如果then的时候成功回调是个null,那么下一个then的成功会掉就是上上个的成功回调返回的值
2.如果then是失败回调是个null,那么下一个then的失败回调就是上上个失败回调返回的值
3.其实原理 then(null /!*result=>result*!/ , null /!* reason=>Promise.reject(reason) *!/ )
catch
1.catch其实就是只处理状态为失败下做的事情
2.实现原理,内部其实就是运行了一个then,返回了一个新的promise,但是这个promise实例,但是这个实例then的时候,成功回调是null,直接穿透了,用上上个then的,所以新的promise实例只有一个参数,就是失败的回调,看备注代码
3.使用,一般项目使用,最后都加个catch
4.其实promise在new时候的,内部也做了一个 try catch的操作,所以只要代码报错了,catch方法就能捕获到
all
race
回调地狱指的就是那种不用promise然后包了很多次success的ajax请求
async(控制函数返回promise实例)
1.函数内部执行报错,则返回失败的promise实例,值是失败的原因
2.自己返回一个promise,以自己返回的为主
3.如果函数内部做了异常捕获,则还是成功态
4.返回一个值,就是返回的一个成功的promise实例,参数为传的值
await
1.面应该放置一个promise实例「我们书写的不是,浏览器也会把其变为promise实例」,await中断函数体中,其下面的代码执行「await表达式会暂停整个async函数的执行进程并出让其控制权」;只有等待await后面的promise实例是成功态之后,才会把之前暂停的代码继续执行,如果后面的promise实例是失败的,则下面的代码就不在执行了;
2.函数体中遇到await,后面代码该咋地咋地,但是下面的代码会暂停执行「把他们当做一个任务,放置在EventQueue的微任务队列中」
3.await是异步的微任务