判断数据类型的方法🌟🌟🌟🌟🌟
- typeof(缺点typeof ull的值为Object,无法分辨是null还是Object)
- instanceof(只能判断对象是否存在于目标对象的原型链上)
- constructor
- Object.prototype.toString.call()
一种最好的基本类型检测方式 Object.prototype.toString.call() ;它可以区分 null 、 string 、
boolean 、 number 、 undefined 、 array 、 function 、 object 、 date 、 math 数据类型。
缺点:不能细分为谁谁的实例
1 | // -----------------------------------------typeof |
instanceof原理🌟🌟🌟🌟🌟
1 | function myInstance(L, R) {//L代表instanceof左边,R代表右边 |
为什么typeof null是Object🌟🌟🌟🌟
因为在JavaScript中,不同的对象都是使用二进制存储的
,如果二进制前三位都是0的话,系统会判断为是Object类型,而null的二进制全是0,自然也就判断为Object
这个bug是初版本的JavaScript中留下的,扩展一下其他五种标识位:
000 对象
1 整型
010 双精度类型
100字符串
110布尔类型
手写call、apply、bind🌟🌟🌟🌟🌟
1.call和apply实现思路主要是:
判断是否是函数调用,若非函数调用抛异常
通过新对象(context)来调用函数
给context创建一个fn设置为需要调用的函数
结束调用完之后删除fn
1 | // 手写call |
2.bind实现思路
判断是否是函数调用,若非函数调用抛异常
返回函数
判断函数的调用方式,是否是被new出来的
new出来的话返回空对象,但是实例的__proto__指向_this的prototype
完成函数柯里化
Array.prototype.slice.call()
1 | Function.prototype.myBind = function(context) { |
字面量创建对象和new创建对象有什么区别,new内部都实现了什么,手写一个new🌟🌟🌟🌟🌟
字面量:
字面量创建对象更简单,方便阅读
不需要作用域解析,速度更快
new内部:
创建一个新对象
使新对象的__proto__指向原函数的prototype
改变this指向(指向新的obj)并执行该函数,执行结果保存起来作为result
判断执行函数的结果是不是null或Undefined,如果是则返回之前的新对象,如果不是则返回result
1 | //手写new |
字面量new出来的对象和 Object.create(null)创建出来的对象有什么区别🌟🌟🌟
- 字面量和new出来的对象会继承Object的属性和方法,他们的隐式原型会指向Object的显示原型
- Object.create(null)创建出来的对象原型为null,作为原型链的顶端,没有继承Object的属性和方法。
什么是作用域什么是作用域链🌟🌟🌟🌟
- 规定变量和函数可使用的范围称为作用域
- 每个函数都有一个作用域,查找变量或者函数时,需要从局部作用域到全局作用域依次查找,这些作用域到集合称为作用域链
什么是执行栈,什么是执行上下文🌟🌟🌟🌟
执行上下文分为:
- 全局执行上下文
创建一个全局的window对象,并规定this执行window,执行js的时候就压入栈底,关闭浏览器的时候才能弹出 - 函数执行上下文
每次函数调用时,都会新创建一个函数执行上下文
执行上下文分为创建阶段和执行阶段
创建阶段:函数环境会创建变量对象:arguments对象(并赋值)、函数声明(并赋值)、变量声明(不赋值),函数表达式声明(不赋值);会确定this指向;会确定作用域
执行阶段:变量赋值、函数表达式赋值,使变量对象编程活跃对象 - eval执行上下文
执行栈:
- 栈的特点
先进后出
- 当进入一个执行环境,就会创建它的执行上下文,然后进行压栈(进栈),当程序执行完成时,它的执行上下文就会被销毁,进行弹栈(出栈)
- 栈底永远是全局环境的执行上下文,栈顶永远是正在执行函数的执行上下文
- 只有浏览器关闭的时候全局执行上下文才会弹出
什么是闭包?闭包的作用?闭包的应用?🌟🌟🌟🌟🌟
函数执行,形成私有的执行上下文,使内部私有变量不受外界干扰,起到保护和保存的作用
关于闭包说法不一 https://zhuanlan.zhihu.com/p/22486908
作用
- 保护
避免变量冲突 - 保存
解决循环绑定引发的索引问题 - 变量不会被销毁
可以使用函数内部的函数,使变量不会被垃圾机制回收
应用
- 设计模式中的单例模式
- for循环中保留i的操作
- 防抖和节流
- 函数柯里化
缺点
会出现内存泄漏
原型和原型链、如何理解🌟🌟🌟🌟🌟
帮助理解 https://www.jianshu.com/p/dee9f8b14771
原型:
原型分为隐式原型和显式原型,每个对象都有一个隐式原型,它指向自己的构造函数的显式原型
原型链:
多个__proto__组成的集合成为原型链
- 所有实例的__proto__都指向他们构造函数的prototype
- 所有的prototype都是对象,自然它的__proto__指向的是Object()的prototype
- 所有的构造函数的隐式原型指向的都是Function()的显示原型
- Object的隐式原型是null
js的继承方式有哪些、及优点🌟🌟🌟🌟🌟
原型继承、组合继承、寄生组合继承、es6extend
原型继承
1 | // 把父类的实例作为子类的原型 |
组合继承
1 | // 在子函数中运行父函数,但是要利用call把this改变一下, |
寄生组合继承
1 | function Father(name) { |
extend继承
1 | class Point { |
内存泄漏、垃圾回收机制🌟🌟🌟🌟🌟
什么是内存泄漏:
内存泄漏是指不在用的内存没有释放出来,导致该段内存无法被使用就是内存泄漏
为什么会导致内存泄漏:
内存泄漏指我们无法在通过js访问某个对象,而垃圾回收机制认为该对象还在被引用,因此垃圾回收机制不会释放该对象,导致该块内存无法被释放,积少成多,系统会越来越卡以至于崩溃
垃圾回收机制都有哪写策略:
- 标记清除法
垃圾回收机制获取根并标记他们,然后访问并标记所有来自它的引用,然后再访问这些对象并标记他们的引用。。。如此递进结束后若发现有没有标记的(不可达的)进行删除,进入执行环境的不能删除 - 引用计数法
1.当声明一个变量并给该变量赋值一个引用类型的值时候,该值的计数+1,当该值赋值给另一个变量的时候,该计数+1,当该值被其他值取代的时候,该计数-1,当计数变为0的时候,说明无法访问该值了,垃圾回收机制清除该对象
2.缺点: 当两个对象循环引用的时候,引用计数无计可施。如果循环引用多次执行的话,会造成崩溃等问题。所以后来被标记清除法取代。
深拷贝浅拷贝🌟🌟🌟🌟🌟
帮助理解 https://www.cnblogs.com/dengyao-blogs/p/11466598.html
浅拷贝:
子对象复制父对象,父子对象发生关联,两者属性值指向同一内存空间。简单来讲,就是改变其中一个对象,另一个对象也会跟着改变。
1 | let a = [1,2,3]; |
深拷贝:
拷贝对象各个层级的属性。简单的讲,就是复制出来的每个对象都有属于自己的内存空间,不会互相干扰。
1 | //借用JSON对象的 parse 和 stringify !! |
hasOwnProperty() 方法详解 https://blog.csdn.net/a791226606/article/details/110679991
为什么js是单线程🌟🌟🌟🌟🌟
因为js里面有可视的DOM,如果是多线程的话,这个线程正在删除DOM节点,另一个线程正在编辑DOM节点,导致浏览器不知道该听谁的。
如何实现异步编程
回调函数
什么是generator
generators 是可以控制 iterator(迭代器)的函数。并在任何时候都可以暂停和恢复。
1 | function * generatorForLoop(num) { |
帮助理解 https://zhuanlan.zhihu.com/p/45599048
Generator是怎么样使用的以及各个阶段的变化如何?🌟🌟🌟
- 首先生成器是一个函数,用来返回迭代器
- 调用生成器后不会立即执行,而是通过返回的迭代器来控制这个生成器一步一步执行的
- 通过调用迭代器的next方法来请求一个一个的值,返回的对象有两个属性,一个是value,也就是值,一个是
done
,是个布尔值类型,done为true说明生成器函数执行完毕,没有可返回的值 - done为true后,继续调用迭代器的next方法,返回值value为
undefined
状态变化
- 每当执行到yield属性的时候,都会返回一个对象
- 这时候生成器处于一个非阻塞的挂起状态
- 调用迭代器的next方法的时候,生成器又从挂起状态变成执行状态,继续上一次执行位置开始执行
- 直到遇到下一次yield依次循环
- 直到代码没有yield了,就会返回一个done为true,value为undefined的对象
说说 Promise 的原理?你是如何理解 Promise 的?🌟🌟🌟🌟🌟
实现原理
说到底,Promise 也还是使用回调函数,只不过是把回调封装在了内部,使用上一直通过 then 方法的链式调用,使得多层的回调嵌套看起来变成了同一层的,书写上以及理解上会更直观和简洁一些。
帮助理解 https://blog.csdn.net/qq_37860963/article/details/81539118
宏任务和微任务有哪些🌟🌟🌟🌟🌟
宏任务:
script,setTimeOut,setInterval,setImmediate
微任务:
Promise.then,process.nextTick,Object.observe,MutationObserve
- Promise是同步任务
宏任务和微任务是怎么执行的🌟🌟🌟🌟🌟
- 执行宏任务中的script
- 进行script后,所有的同步任务主线程执行
- 所有的宏任务放入宏任务执行队列
- 所有的微任务放入微任务执行队列
- 先清空微任务队列
- 再取一个宏任务执行,再清空微任务队列
- 依次循环
例题1
1 | setTimeout(function(){ |
解析
- 首先js浏览器执行js代码从上到下顺序,遇到setTimeout,把setTimeout放到宏任务执行队列
- new Promise属于主线程任务直接执行 2
- promise.then下面属于微任务,把then放到微任务的执行队列
- console.log(‘4’);属于主线程任务直接执行 4
- 又遇到new Promise属于主线程直接执行 5,下面的then放到微任务执行队列
- 又遇到setTimeout,把setTimeout放到宏任务执行队列
- console.log(‘10’)属于主线程任务直接执行 10
- 遇到bar()函数调用,执行bar函数打印 8 在bar函数中调用foo()执行打印 9
- 主线程的任务都执行完之后,去执行微任务队列中的任务执行 3, 6
- 微任务队列中的任务执行完之后,执行宏任务队列中的任务执行1, 7
例题2
1 | setTimeout(() => { |
变量和函数怎么进行提升的?优先级是怎么样的?🌟🌟🌟🌟
- 对所有函数声明进行了提升(除函数表达式和箭头函数),引用类型的赋值
开辟堆空间
存储内容
将地址赋给变量 - 对变量声明进行提升,只声明不赋值,值为undefined
var let const 有什么区别🌟🌟🌟🌟🌟
- var
var声明的变量可以进行变量提升,let const没有
var可以重复声明
var在飞函数作用域中定义是挂载到window上的 - let
let声明的变量在才局部起作用
let防止变量污染
不可再声明 - const
具有let的所有特征
不可被改变
如果const声明的是对象的话,是可以修改对象里面的值的
箭头函数和普通函数的区别?箭头函数可以当做构造函数 new 吗?🌟🌟🌟🌟🌟
- 箭头函数是普通函数的简写,但是他不具备很多普通函数的特征
- 1.this指向问题,箭头函数的this指向它定义时所在的对象,而不是调用时所在的对象
- 2.不会进行函数提升
- 3.没有arguments对象,不能使用arguments,如果要获取参数的话要使用rest运算符
- 4.没有yield属性,不能作为生成器gengenerator使用
- 5.不能new
没有自己的this,不能调用call和apply
没有prototype,new关键字内部需要把新对象的__proto__指向函数的prototype
说说你对代理的理解🌟🌟🌟
代理有几种定义方式:
- 字面量定义,对象里面的get和set
- 类定义,类里面的get和set
- Proxy对象,里面传两个对象,第一个对象是目标对象target,第二个对象是专门放get和set的handler对象。Proxy和上面两个的区别在于Proxy专门对对象的属性进行get和set
代理的实际应用有:
- Vue的双向绑定vue2用的是Object.definProperty,vue3用的是proxy
- 校验值
- 计算属性值(get的时候加以修饰)
Object.definProperty 帮助理解https://blog.csdn.net/weixin_46726346/article/details/115913752
为什么要使用模块化🌟🌟🌟
- 防止命名冲突
- 更好分离按需加载
- 更好的复用性
- 更高的维护性
exports和module.exports有什么区别?🌟🌟🌟
- 导出方式不一样
exports.xxx = ‘xxx’
module.export = {} - exports是module.exports的引用,两个指向的是用一个地址,而require能看到的只有module.exports
js模块包格式有哪些?🌟🌟🌟
帮助理解 https://www.cnblogs.com/qdwz/p/10718536.html
- common.js
同步运行,不适合前端 - AMD
异步运行
异步模块定义,主要采用异步的方式加载模块,模块的加载不影响后面代码的执行。所有依赖这个模块的语句都写在一个回调函数中,模块加载完毕,再执行回调函数 - CMD
异步运行
seajs 规范
ES6和commonjs的区别🌟🌟
- commonjs模块输出的是值的拷贝,而ES6输出的值是值的引用
- commonjs是在运行时加载,是一个对象,ES6是在编译时加载,是一个代码块
- commonjs的this指向当前模块,ES6的this指向undefined
跨域的方式都有哪些?他们的特点是什么 🌟🌟🌟🌟🌟
https://blog.csdn.net/ligang2585116/article/details/73072868?locationNum=13&fps=1
HTTP的结构🌟🌟🌟🌟
- 请求行 请求头 空行 请求体
请求行包括 http版本号,url,请求方式
响应行包括版本号,状态码,原因
说说你知道的状态码🌟🌟🌟🌟🌟
- 2开头的表示成功
一般见到的就是200 - 3开头的表示重定向
301永久重定向
302临时重定向
304表示可以在缓存中取数据(协商缓存) - 4开头表示客户端错误
403跨域
404请求资源不存在 - 5开头表示服务端错误
500
网络OSI七层模型都有哪些?TCP是哪一层的🌟🌟🌟🌟
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
TCP属于传输层
http1.0和http1.1,还有http2有什么区别?🌟🌟🌟🌟
- http0.9只能进行get请求
- http1.0添加了POST,HEAD,OPTION,PUT,DELETE等
- http1.1增加了长连接keep-alive,增加了host域,而且节约带宽
- http2
https和http有什么区别,https的实现原理?🌟🌟🌟🌟🌟
- http无状态无连接,而且是明文传输,不安全
- https传输内容加密,身份验证,保证数据完整性
- https实现原理⭐⭐⭐⭐⭐
首先客户端向服务端发起一个随机值,以及一个加密算法
服务端收到后返回一个协商好的加密算法,以及另一个随机值
服务端在发送一个公钥CA
客户端收到以后先验证CA是否有效,如果无效则报错弹窗,有过有效则进行下一步操作
客户端使用之前的两个随机值和一个预主密钥组成一个会话密钥,在通过服务端传来的公钥加密把会话密钥发送给服务端
服务端收到后使用私钥解密,得到两个随机值和预主密钥,然后组装成会话密钥
客户端在向服务端发起一条信息,这条信息使用会话秘钥加密,用来验证服务端时候能收到加密的信息
服务端收到信息后返回一个会话秘钥加密的信息
都收到以后SSL层连接建立成功
localStorage、SessionStorage、cookie、session 之间有什么区别🌟🌟🌟🌟🌟
- localStorage
生命周期:关闭浏览器后数据依然保留,除非手动清除,否则一直在
作用域:相同浏览器的不同标签在同源情况下可以共享localStorage - SessionStorage
生命周期:关闭浏览器或者标签后即失效
作用域:只在当前标签可用,当前标签的iframe中且同源可以共享 - cookie
是保存在客户端的,一般由后端设置值,可以设置过期时间
储存大小只有4K
一般用来保存用户的信息的
在http下cookie是明文传输的,较不安全
cookie属性有:
http-only:不能被客户端更改访问,防止XSS攻击(保证cookie安全性的操作)
Secure:只允许在https下传输
Max-age: cookie生成后失效的秒数
expire: cookie的最长有效时间,若不设置则cookie生命期与会话期相同
- session
session是保存在服务端的
session的运行依赖sessionId,而sessionId又保存在cookie中,所以如果禁用的cookie,session也是不能用的,不过硬要用也可以,可以把sessionId保存在URL中
session一般用来跟踪用户的状态
session 的安全性更高,保存在服务端,不过一般为使服务端性能更加,会考虑部分信息保存在cookie中
怎么使用cookie保存用户信息🌟🌟🌟
document.cookie(“名字 = 数据;expire=时间”)
https://bbs.csdn.net/topics/250052356
怎么删除cookie🌟🌟🌟
目前没有提供删除的操作,但是可以把它的Max-age设置为0,也就是立马失效,也就是删除了
get和post的区别🌟🌟🌟🌟🌟
- 冪等/不冪等(可缓存/不可缓存)
get请求是冪等的,所以get请求的数据是可以缓存的
而post请求是不冪等的,查询查询对数据是有副作用的,是不可缓存的 - 传参
get传参,参数是在url中的
准确的说get传参也可以放到body中,只不过不推荐使用
post传参,参数是在请求体中
准确的说post传参也可以放到url中,只不过不推荐使用 - 安全性
get较不安全
post较为安全
准确的说两者都不安全,都是明文传输的,在路过公网的时候都会被访问到,不管是url还是header还是body,都会被访问到,要想做到安全,就需要使用https - 参数长度
get参数长度有限,是较小的
准确来说,get在url传参的时候是很小的
post传参长度不受限制 - 发送数据
post传参发送两个请求包,一个是请求头,一个是请求体,请求头发送后服务器进行验证,要是验证通过的话就会给客户端发送一个100-continue的状态码,然后就会发送请求体 - 字符编码
get在url上传输的时候只允许ASCII编码
在浏览器输入url后发生了什么🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
https://www.jianshu.com/p/7eea6fbc5fcd
1.浏览器的地址栏输入URL并按下回车。
2.浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
3.DNS解析URL对应的IP。
4.根据IP建立TCP连接(三次握手)。
5.HTTP发起请求。
6.服务器处理请求,浏览器接收HTTP响应。
7.渲染页面,构建DOM树。
8.关闭TCP连接(四次挥手)。
什么是xss?什么是csrf?🌟🌟🌟🌟🌟
- xss脚本注入
不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)。
防御
编码:对用户输入的数据进行HTML Entity 编码。把字符转换成 转义字符。Encode的作用是将$var等一些字符进行转化,使得浏览器在最终输出结果上是一样的。
过滤:移除用户输入的和事件相关的属性。 - csrf跨域请求伪造
在未退出A网站的前提下访问B,B使用A的cookie去访问服务器
防御:token,每次用户提交表单时需要带上token(伪造者访问不到),如果token不合法,则服务器拒绝请求
什么是回流 什么是重绘?🌟🌟🌟🌟🌟
渲染树(render树)是什么 https://zhuanlan.zhihu.com/p/121807893
什么是回流 什么是重绘和区别https://www.jianshu.com/p/e081f9aa03fb
- 回流
render树中一部分或全部元素需要改变尺寸、布局、或着需要隐藏而需要重新构建,这个过程叫做回流
回流必将引起重绘 - 重绘
render树中一部分元素改变,而不影响布局的,只影响外观的,比如颜色。该过程叫做重绘 - 区别
回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流
当页面布局和几何属性改变时就需要回流
比如:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变
事件冒泡和事件捕捉有什么区别🌟🌟🌟🌟🌟
- 事件冒泡
在addEventListener中的第三属性设置为false(默认)
从下至上(儿子至祖宗)执行 - 事件捕获
在addEventListener中的第三属性设置为true
从上至下(祖宗到儿子)执行
什么是防抖?什么是节流?手写一个🌟🌟🌟🌟🌟
帮助理解防抖 https://blog.csdn.net/woshidamimi0/article/details/99705915
- 防抖
n秒后在执行该事件,若在n秒内被重复触发,则重新计时 - 节流
n秒内只运行一次,若在n秒内重复触发,只有一次生效
1 | //防抖函数 |
函数柯里化原理🌟🌟🌟🌟🌟
1 | function add() { |
什么是requestAnimationFrame?🌟🌟🌟🌟
帮助理解 https://www.jianshu.com/p/fa5512dfb4f5
requestAnimationFrame请求数据帧可以用做动画执行
可以自己决定什么时机调用该回调函数
能保证每次频幕刷新的时候只被执行一次
页面被隐藏或者最小化的时候暂停执行,返回窗口继续执行,有效节省CPU
js常见的设计模式🌟🌟🌟🌟🌟
单例模式、工厂模式、构造函数模式、发布订阅者模式、迭代器模式、代理模式、观察者模式
工厂模式和构造函数模式的异同 https://blog.csdn.net/liumuye88888/article/details/115561044
观察者模式和订阅者模式理解 https://zhuanlan.zhihu.com/p/351750593
- 单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
帮助理解单例模式 https://zhuanlan.zhihu.com/p/34754447 知乎
1 | //惰性单例 |
上面的timeTool实际是一个函数,——instance作为实例对象最开始赋值为null,init函数是其构造函数,用于实例化对象,立即执行函数返回的是匿名函数用于判断实例是否创建,只有当调用timeTool()时进行实例化,这就是惰性单例的应用,不在js加载时就进行实例化创建,而是在需要的时候再进行单例的创建。如果再次调用,那么返回的永远是第一次实例化后的实例对象
- 工厂模式
代替new创建一个对象,且这个对象像工厂制作一样,批量制作属性相同的实例对象(指向不同)
1 | function createFactory(name,age,gender){ |
JS性能优化的方式🌟🌟🌟🌟🌟
避免使用全局变量
图片优化(雪碧图)
懒加载
垃圾回收
闭包中的对象清除
防抖节流
分批加载(setInterval,加载10000个节点)
事件委托
少用with
requestAnimationFrame的使用
script标签中的defer和async
CDN
vue数据劫持
帮助理解 https://yuchengkai.cn/docs/frontend/framework.html#mvvm
vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
阐述一下你所理解的MVVM响应式原理🌟🌟🌟🌟🌟
Vue 采用数据劫持结合发布者-订阅者模式的方式通过 Object.defineProperty() 劫持并监听各个属性的 setter 和 getter,在数据变动时,发布消息给依赖收集器,通知观察者,调用相应的回调函数,进而更新视图
MVVM 作为入口函数,整合 Observer、Compile、Watcher 三者,通过 Observer 监听数据变化,通过 Compile 解析编译模版指令,通过 Watcher 连接 Observer 和 Compile ,达到数据更新时视图更新,视图交互更新时数据更新的双向绑定效果
订阅器(dep):通知订阅者更新视图,存放多个订阅器
订阅者(watcher):更新视图
observer:劫持属性
compile:解析指令
原文链接:https://www.cnblogs.com/veinyin/p/12640058.html
vue生命周期🌟🌟🌟🌟🌟
- beforeCreate
创建之前还没有data和model - created
创建完成,此时data和method可以使用了
在created之后beforeMount之前如果没有el选项的话那么此时生命周期结束,停止编译,如果有则继续 - beforeMount
在渲染之前 - mounted
页面已经渲染完成,并且vm实例已经添加完成$el,已经替换掉哪些dom元素(双括号中的变量),这个时候可以操作DOM了(但是是获取不了元素的高度等属性的,如果想要获取,需要使用nextTick()(仅在整个视图都被渲染之后才会运行的代码)) - beforeUpdate
data
改变后,对应的组件重新渲染之前 - updated
data
改变后,对应的组件渲染完成 - activated
被 keep-alive 缓存的组件激活时调用。
该钩子在服务器端渲染期间不被调用。 - beforeDestory
在实例销毁之前,此实例仍然可以使用 - destoryed
实例销毁后
vue-router的模式🌟🌟🌟🌟🌟
Vue-router 中hash模式和history模式的区别 https://zhuanlan.zhihu.com/p/337073166
- hash模式
监听hashchange事件实现前端路由,利用url中的hash来模拟一个hash,以保证url改变时,页面不会重新加载。 - history模式
利用pushstate和replacestate来将url替换但不刷新,但是有一个致命点就是,一旦刷新的话,就会可能404,因为没有当前的真正路径,要想解决这一问题需要后端配合,将不存在的路径重定向到入口文件。
什么是diff算法🌟🌟🌟🌟🌟
diff算法是指新旧虚拟dom节点进行对比,并返回一个patch对象,用来存储两个节点不同的地方,最后利用patch记录的消息局部更新dom
虚拟dom的优缺点🌟🌟🌟🌟🌟
- 缺点
首次渲染大量dom时,由于多了一层虚拟dom的计算,会比innerHtml插入慢 - 优点
减少dom操作,减少了回流与重绘
能跨平台渲染:因为虚拟DOM本质只是一个JS对象,所以虚拟DOM不仅可以改变DOM,还可以变成小程序,iOS应用,安卓应用等
保证了性能的下限,虽然性能不是最佳,但是它具备局部更新的能力,所以大部分的时候还是比正常的dom性能好很多
Vue的Key的作用🌟🌟🌟🌟🌟
key主要是用于虚拟dom算法中,每个虚拟节点有一个唯一标识key,通过对比新旧节点的key来判断节点是否改变,用key就可以大大提高渲染效率,这个key类似于缓存中的etag。
Vue组件之间的通信方式🌟🌟🌟🌟🌟
组件通信大全 https://www.cnblogs.com/fundebug/p/10884896.html
- 父传子
子组件通过props接受父组件传递的值 - 子传父
子组件$emit(‘事件名’,值),父组件v-on/@接收 - 任意组件通信,新建一个空的全局Vue对象,利用emit发送,emit发送,on接收
1 | Vue.prototype.Event=new Vue(); |
vuex也可以传值
Vue-router有哪几种钩子函数
参考 https://www.jianshu.com/p/ddcb7ba28c5e
https://www.zhihu.com/search?type=content&q=路由钩子函数
- 全局钩子
1 | ```afterEach进```入之后触发 |
- mode设计模式
- module(loader)
里面有一个rules数组对某种格式的文件进行转换处理(转换规则)
use数组解析顺序是从下到上逆序执行的
1 | module:{ |
- plugin(铺类根)插件配置
1 | const uglifyJsPlugin = reqiure('uglifyjs-webpack-plugin') |
- devServer(热更新)
1 | devServer:{ |
- resolve(配置路径规则)
alias 别名
1 | module.exports= { |
- babel(ES6转ES5)
下载插件babel-loader,在module(loader)中配置
loader和plugin的区别是什么?🌟🌟🌟
- loader
loader是用来解析非js文件的,因为Webpack原生只能解析js文件,如果想把那些文件一并打包的话,就需要用到loader,loader使webpack具有了解析非js文件的能力 - plugin
用来给webpack扩展功能的,可以加载许多插件
flext布局🌟🌟🌟🌟🌟
阮一峰 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
grid布局🌟🌟🌟🌟
https://www.cnblogs.com/cythia/p/10894598.html
first-of-type和first-child有什么区别🌟🌟🌟🌟
https://www.cnblogs.com/2050/p/3569509.html
- first-of-type
匹配的是从第一个子元素开始数,匹配到的那个的第一个元素 - first-child
必须是第一个元素
doctype标签和meta标签🌟🌟🌟🌟🌟
- doctype
告诉浏览器以什么样的文档规范解析文档 - meta
最简单的理解就是设置这个页面的编码格式,不然会出现中英文乱码
script标签中defer和async都表示了什么🌟🌟🌟🌟🌟
帮助理解 https://www.cnblogs.com/jiasm/p/7683930.html
众所周知script会阻塞页面的加载,如果我们要是引用外部js,假如这个外部js请求很久的话就难免出现空白页问题,好在官方为我们提供了defer和async
- defer
1 | <script src="d.js" defer></script> |
不会阻止页面解析,并行下载对应的js文件
下载完之后不会执行
等所有其他脚本加载完之后,在DOMContentLoaded事件之前执行对应d.js、e.js
- async
1 | <script src="b.js" async></script> |
不会阻止DOM解析,并下载对应的js文件
下载完之后立即执行
- 补充,DOMContentLoaded事件
是等HTML文档完全加载完和解析完之后运行的事件
在load事件之前
不用等样式表、图像等完成加载
什么是BFC🌟🌟🌟🌟🌟
帮助理解 https://zhuanlan.zhihu.com/p/184905483
- BFC是一个独立渲染区域,它丝毫不会影响到外部元素
- BFC特性
同一个BFC下的margin会重叠
计算BFC高度时会算上浮动元素
BFC不会影响到外部元素
BFC内部元素是垂直排列的
BFC区域不会与float元素重叠 - 如何创建BFC
position设为absolute或者fixed
float不为none
overflow设置为hidden
display设置为inline-block或者inline-table或flex
如何清除浮动🌟🌟🌟🌟🌟
- 1.额外标签clear:both
1 | <!DOCTYPE html> |
- 2.利用BFC
overflow:hidden || auto
1 | .fahter{ |
- 3.给前面的父元素设置高度,不推荐使用
- 4.使用after(推荐)
1 | <style> |
- 5.使用before和after双伪元素清除浮动
1 | .clearfix:after,.clearfix:before{ |
垂直水平居中的几种方法🌟🌟🌟🌟🌟
- 1.第一种方法
子元素绝对定位,上下左右为0,margin:auto;
1 | <!DOCTYPE html> |
- 2.弹性布局
1 | <!DOCTYPE html> |
- 3.定位 + margin-top + margin-left
1 | <!DOCTYPE html> |
设置父元素的position为相对定位,子元素绝对定位,并在 top 和 left 方向上移动父元素50%的距离。
但这个时候,是子元素的上边框和左边框距离父元素150px,整体向右下角偏了一些,所以还需要再用 margin 调整至中心位置,数值分别是高度和宽度的一半。
- 4.display: table-cell 无兼容性问题(文字居中)
1 | .box { |
只需要设置父元素即可,text-align: center; 并在竖直方向上令内容居中(middle),早期属性,不存在兼容问题。
什么是DOM事件流?什么是事件委托🌟🌟🌟🌟🌟
- DOM时间流分成三个阶段
捕获阶段
目标阶段
冒泡阶段
在addeventListener()的第三个参数(useCapture)设为true,就会在捕获阶段运行,默认是false冒泡 - 事件委托
利用冒泡原理(子向父一层层穿透),把事件绑定到父元素中,以实现事件委托
算法
- 1.冒泡排序🌟🌟🌟🌟🌟
1 | function bubbleSort(arr){ |
- 2.快速排序🌟🌟🌟🌟🌟
从数组中选择一个元素作为基准点
排序数组,所有比基准值小的元素摆放在左边,而大于基准值的摆放在右边。每次分割结束以后基准值会插入到中间去。
最后利用递归,将摆放在左边的数组和右边的数组在进行一次上述的1和2操作。
1 | function quickSort(arr){ |
- 3.插入排序🌟🌟🌟🌟
1 | function insertSort(arr){ |
- 4.是否回文🌟🌟🌟🌟🌟
1 | function isHuiWen(str){ |
- 5.斐波那契数列🌟🌟🌟🌟🌟
1 | // num1前一项 |
git 🌟🌟🌟🌟🌟
https://blog.csdn.net/qq_36095679/article/details/91804051
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !