2021前端面试题

编程入门 行业动态 更新时间:2024-10-27 16:27:59
问题答案
1、cookie、localStorage 和 sessionStorage 的区别?cookie数据保存在客户端,session数据保存在服务器端
有效时间:
localStorage存储持久数据,没有时间限制,浏览器关闭后数据不丢失,除非主动删除数据。
sessionStorage数据在当前浏览器窗口关闭后自动删除。
作用域:
sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面。
localStorage 在所有同源窗口中都是共享的。
数据传递:
cookie数据始终在同源的http请求中携带(即使不需要),即会在浏览器和服务器间来回传递。
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
存储大小:
cookie数据大小不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。
sessionStorage和localStorage 虽然也有存储大小的限制,但Web Storage数据完全存储在客户端,不需要通过浏览器的请求将数据传给服务器,因此相比cookie来说能够存储更多的数据,可以达到5M或更大。

 
2、hash和history的区别?1、hash模式下,仅hash符号之前的内容会被包含在请求中,如 http://www.abc 因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回404错误;hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中。hash 只可修改 # 后面的部分,因此只能设置与当前 URL 同文档的 URL。hash 只可添加短字符串。

2、history模式下,前端的url必须和实际后端发起请求的url一致,如http://www.abc/book/id 。如果后端缺少对/book/id 的路由处理,将返回404错误。
利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)
这两个方法应用于浏览器的历史记录栈,在当前已有的 back()、forward()、go() 方法的基础之上,这两个方法提供了对历史记录进行修改的功能。当这两个方法执行修改时,只能改变当前地址栏的 URL,但浏览器不会向后端发送请求,也不会触发popstate事件的执行
3、Vue生命周期?vue实例从创建到挂载到更新,最后销毁,这整个流程叫做vue的生命周期

生命周期钩子函数
// 初始化构建阶段
beforeCreate vue实例初始化完成之前,完成了vue事件、属性的初始化,但是访问不到vue实例中的data、methods
created vue实例初始化完成,可以访问实例内部的数据和方法
// 挂载阶段
beforeMount 完成了模板的解析,但是数据没有绑定到模板上
mounted vm.$el虚拟dom替换el Dom,完成了数据绑定。
// 更新阶段
beforeUpdate 数据以及修改,虚拟dom也构建完毕,但是没有渲染到页面上
updated 更新过后的虚拟dom节点,成功渲染到页面上
// 销毁阶段 this.$destroy()
beforeDestroy vue实例销毁之前,还可以访问实例
destroyed vue实例上绑定的事件、监听器、子组件销毁完毕,访问不到vue实例了
4、为什么会出现跨域以及如何解决?出于浏览器的同源策略限制。
同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。
所谓同源(即指在同一个域)就是两个页面具有相同的协议,域名和端口号
当一个请求url的协议,域名,端口三者之间任意一个与当前页面url不同即为跨域

克服跨域限制的方法有
(1)通过jsonp跨域
(2)通过修改document.domain来跨子域
(3)使用window.name来进行跨域
(4)使用HTML5中新引进的window.postMessage方法来跨域传送数据
(5)使用代理服务器
(6)CORS跨域资源共享
https://blog.csdn/weixin_43739375/article/details/88587416
5、mutations和actions的区别?actions可以进行异步操作,用于向后台提交数据或者接受后台的数据;
mutations中是同步操作,用于将数据信息写在全局数据状态中缓存
6、watch和computed的区别?计算属性computed :

1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3puted 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

侦听属性watch:

1. 不支持缓存,数据变,直接会触发相应的操作;
2.watch支持异步;
3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4. 当一个属性发生变化时,需要执行对应的操作;一对多;
5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
  immediate:组件加载立即触发回调函数执行,
  deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
7、简单的说一下ES6的方法?es6新增对象方法
Object.is():相当于‘===’,接受两个参数两个类型相同且具有相同的值为true,
console.log(Object.is(NaN,NaN)) //true
console.log(Object.is(+0,-0)) //false
Object.assign():两个参数实现对象复制、拷贝 第一个参数是目标对象,(只能实现表面的深拷贝,如果obj是一个只有一层 的对象,能实现深拷贝,但是如果obj的对象超过一层,那么只有最外层的对象的key,value值能实现深拷贝,里层嵌套的 对象无法实现深拷贝,只是引用地址的浅拷贝
Object.keys():获取所有属性名组成的数组
Object.values():获取所有属性值组成的数组
Object.entries():获取所有键值对组成的数组

es6新增数组方法
Array.from():将类数组对象转换成数组
Array.of():将传入的参数组成数组
Array.prototype.find((item)=>{}) find方法返回第一个满足条件的元素或者undefined 参数回调函数
Array.prototype.includes(); includes是否包含某个元素,返回true/false

 
es6新的语法1.不一样的变量声明:const和let
2.模板字符串:ES6反引号(``)
3.箭头函数: 不需要 function 关键字来创建函数,省略 return 关键字,继承当前上下文的 this 关键字
4. 函数的参数默认值:function printText(text = 'default') {console.log(text);//不传入参数默认值为default}
5.扩展运算符/剩余运算符:用于迭代器中是扩展运算符,用于传入参数时是剩余运算符
6.二进制和八进制字面量:ES6 支持二进制和八进制的字面量,通过在数字前面添加 0o 或者0O 即可将其转换为八进制值
7.对象和数组解构:const { name, age, sex } = student;
8.对象超类
9.for...of 和 for...in:for...of 用于遍历一个迭代器,如数组;for...in 用来遍历对象中的属性
10.ES6中的类:ES6 中支持 class 语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。
函数中使用 static 关键词定义构造函数的的方法和属性:
https://www.jianshu/p/87008f4f8513
8、promise机制?pending进行中 resolved已完成 rejected已拒绝 一旦从进行状态变成其他状态就永远不能更改状态了 无法取消promise
9、vuex的组成部分?state:用来存放组件之间共享的数据。他跟组件的data选项类似,只不过data选项是用来存放组件的私有数据。

getters:我们需要对state的数据进行筛选,过滤。这些操作都是在组件的计算属性进行的。如果多个组件需要用到筛选后的数据,那我们就必须到处重复写该计算属性函数;或者将其提取到一个公共的工具函数中,并将公共函数多处导入 - 两者都不太理想。如果把数据筛选完在传到计算属性里就不用那么麻烦了,getters就是干这个的,你可以把getters看成是store的计算属性。getters下的函数接收接收state作为第一个参数。那么,组件是如何获取经过getters过滤的数据呢? 过滤的数据会存放到$store.getters对象中

mutations:前面讲到的都是如何获取state的数据,那如何把数据存储到state中呢?在 Vuex store 中,实际改变 状态(state) 的唯一方式是通过 提交(commit) 一个 mutation。  mutations下的函数接收state作为参数,接收一个叫做payload(载荷)的东东作为第二个参数,这个东东是用来记录开发者使用该函数的一些信息,比如说提交了什么,提交的东西是用来干什么的,包含多个字段,所以载荷一般是对象(其实这个东西跟git的commit很类似)还有一点需要注意:mutations方法必须是同步方法!

actions:可以提交mutation方法,通过mutation来改变state,可以接收一个context对象,通过context.state 和 context.getters来改变state。可以执行任意的同步和异步操作

 
10、闭包是什么?优缺点?闭包问题如何解决函数内部的函数,函数内部可以引用函数外部的变量,闭包使用的变量和参数不会被垃圾回收机制销毁

2、优点:可以读取自身函数外部的变量(延作用域链寻找),变量缓存,避免命名冲突

3、缺点:容易发生内存泄漏,使用过多时消耗内存

适用场景:return 返回一个函数;函数作为参数如数组api的foreach,map等的参数为匿名函数;防抖和节流

怎么解决:在退出函数之前,将不使用的局部变量全部赋值为null;避免变量的循环赋值和引用

 
11、HTTP的请求方式?get,post,head,put,delete,options, trace和 connect方法

get(查询)和post(保存)的区别?

get 请求时参数拼接在url后 /user/deleteById?id=1; 可以在浏览器地址栏中看到

post请求时参数放在请求体中;参数不可见;安全,参数量多一些
12、promise实例的使用场景Promise可以用来避免异步操作函数里的回调地狱问题,因为解决异步最直接的方法是回调嵌套,将后一个的操作放在前一个操作的异步回调里,但如果操作多了,就会有很多层的嵌套。
1.实现串行任务队列,任务队列是指A完成了调用B,B完成了调用C,消除了回调地狱,链式调用 + 错误自动后抛
2.实现串行任务管道,任务管道是指当前任务的输出可以作为下一个任务的输入,形成一条数据管道
3.处理运行时才能确定执行顺序的串行任务,假设有A,B,C3个任务,执行顺序不确定,有可能是BCA、BAC等等,运行时才能确定3者的执行顺序,一旦确定顺序,就要立即串行执行
13、CSS选择器优先级权重
行内样式 1000
id选择器 100
属性选择器、class或者伪类 10
元素选择器、伪元素 1
通配符 0
优先级
1. 权重相同,写在后面的覆盖前面的
2. 使用 !important 达到最大优先级,都使用 !important 时,权重大的优先级高
14、水平居中,垂直居中的方法子绝父相
flex
15、说出数组的方法以及如何使用Array.from() 将其他类型数据(可迭代的)转成数组
Array.of() 创建数组实例,实参就是数组的元素
Array.prototype.find() 返回满足条件的第一个元素,参数为函数
Array.prototype.findIndex() 返回满足条件的第一个元素的索引,参数为函数
Array.prototype.includes() 判断当前数组中是否包含某个元素,参数为元素,返回true/false
Array.prototype.fill() 填充数组(所有元素填充),修改数组原值
Array.prototype.() 索引的迭代器对象
Array.prototype.values() 元素的迭代器对象
Array.prototype.entries() 键值对的迭代器对象
Array.prototype.concat() 方法用于连接两个或多个数组
Array.prototype.join() 方法用于把数组中的所有元素放入一个字符串,元素是通过指定的分隔符进行分隔的
Array.prototype.pop() 方法用于删除并返回数组的最后一个元素,会改变原数组。
Array.prototype.push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
Array.prototype.reverse() 方法用于颠倒数组中元素的顺序。
Array.prototype.shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
16、JS指针是什么?(连老师都不知道的问题,数跑是怎么
找的题???)
17、说一下防抖和节流以及使用场景?防抖:
触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
(每次触发事件时都取消之前的延时调用方法)
适用场景:
search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发

节流:
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
(每次触发事件时都判断当前是否有等待执行的延时函数)
使用场景:
鼠标不断点击触发,mousedown(单位时间内只触发一次)
监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
18、网页加载速度慢,该怎么排查?第一种,看一下网络是否连接成功
第二种,图片懒加载
19、说一下什么是懒加载懒加载原理:
一张图片就是一个<img>标签,浏览器是否发起请求图片是根据<img>的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给<img>的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。
使用场景:懒加载也加延迟加载,延迟加载网络资源或符合某些条件时才加载资源。常见的就是图片延时加载。
网站上图片量比较大,考虑用户性能,懒加载的主要目的是作为服务器前端的优化,减少请求数或延 迟请求数。
20、什么是垃圾回收机制为何要垃圾回收?
JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,
最终都要释放这些内存以便他们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。

垃圾收集机制的原理:
垃圾收集器会按照固定的时间间隔,周期性的找出不再继续使用的变量,然后释放其占用的内存。

什么叫不再继续使用的变量?
不再使用的变量也就是生命周期结束的变量,是局部变量,局部变量只在函数的执行过程中存在,当函数运行结束,没有其他引用(闭包),那么该变量会被标记回收。

全局变量的生命周期直至浏览器卸载页面才会结束,也就是说全局变量不会被当成垃圾回收。
21、js的事件循环机制(event loop)所有的任务可以分为同步任务和异步任务,
同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;
异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列( Event Queue )的机制来进行协调。
同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 Event Queue 。主线程内的任务
执行完毕为空,会去 Event Queue 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的事件循环。
宏任务与微任务JS分为同步任务和异步任务同步任务都在主线程上执行,形成一个执行栈主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放置一个事件。一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在宏任务的队列中取出第一个任务,执行完毕后取出微任务 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。
https://www.jianshu/p/2a5954b78ff5
22、get 和 post 的区别GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
GET参数通过URL传递,POST放在Request body中。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET在浏览器回退时是无害的,而POST会再次提交请求。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET产生一个TCP数据包;POST产生两个TCP数据包。
23、promise和async await的区别
Promise,简单来说就是一个容器,里面保存着某个未来才会结束的时间(通常是一个异步操作的结果)
promise共有三个状态-------->>>pending(执行中)、success(成功)、rejected(失败)

async/await与promise不存在谁代替谁的说法,因为async/await是寄生于Promise,Generater的语法糖。
async用于申明一个function是异步的,而await可以认为是async wait的简写,等待一个异步方法执行完成。
规则:
1 async和await是配对使用的,await存在于async的内部。否则会报错
2 await表示在这里等待一个promise返回,再接下来执行
3 await后面跟着的应该是一个promise对象

1、 promise是ES6,async/await是ES7
2、 async/await相对于promise来讲,写法更加优雅
3、 reject状态:
1)promise错误可以通过catch来捕捉,建议尾部捕获错误,
2)async/await既可以用.then又可以用try-catch捕捉
24、判断数组的方法① instanceof 操作符判断 用法:arr instanceof Array
②对象构造函数的 constructor判断 用法:arr.constructor === Array
③Array 原型链上的 isPrototypeOf 用法:Array.prototype.isPrototypeOf(arr)
④Object.getPrototypeOf 用法:Object.getPrototypeOf(arr) === Array.prototype
⑤Object.prototype.toString 用法:Object.prototype.toString.call(arr) === '[object Array]'
⑥Array.isArray 用法:Array.isArray(arr)
25、watch怎么监听数据的变化一个普通的值,当值变化时会被监听到,一个对象,不能直接像值那么写,需要深度监听才能捕捉到,
但是当我想去捕捉b对象中某一个值的变化时却发现,打印出来的两个值是不一样的

(1)通过watch监听data数据的变化,数据发生变化时,就会打印当前的值
(2)通过watch监听docData数据的变化,数据发生变化时,this.change_number++(使用深度监听)
(3)通过watch监听data数据的变化,数据发生变化时,执行changeData方法
26、讲一下TCP三次握手和四次挥手TCP三次握手是建立连接连接过程,三握手结束后才开始传数据

为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送 后的情况置之不理,它一定会向对方确认是否成功送达。握手过程中使用了TCP的标志:SYN和ACK。

发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。
最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。
若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。


四次挥手是关闭连接的过程

§ 第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。

§ 第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。

§ 第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。

§ 第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。

 
27、TCP协议和UDP协议的区别1.tcp是面向连接的,udp是无连接的
2.tcp提供可靠的服务无差错且按序到达,udp尽最大努力交付,不保证可靠交付
3.tcp是面向字节流,udp面向报文,且网络出现拥塞不会使得发送速率降低
4.tcp只能是一对一的,udp支持一对一,一对多,多对多
5.tcp的首部为20字节,udp只有8字节
6.tcp适用于文件传输,邮件传输等;udp适合即时通讯,在线视频,语音通话等
7.TCP的逻辑通信信道是全双工的可靠信道,UDP是不可靠信道
28、说一下什么是深拷贝、浅拷贝1、浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

2、深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
30、vue中如何获取元素节点1、利用js原生的获取dom节点的方法:document.getElementById等

2、可以在vue项目中引入jquery

3、可以在vue项目中利用vue提供的api在dom标签的属性上加上一个ref="dom的名字"属性,然后通过vue实例的this.$refs.dom的名字来直接获取这个元素节点,
31、vue的ajaxwindow.onload = function(){
var vm = new Vue({
el:'#box',
data:{
msg:'Hello World!',
},
methods:{
get:function(){
//发送get请求
this.$http.get('/try/ajax/ajax_info.txt').then(function(res){
document.write(res.body);
},function(){
console.log('请求失败处理');
});
}
}
});
}
32、自己封装一个完整的ajaxajax方法封装_zuo_zuo_blog的博客-CSDN博客_ajax封装
33、keep-alivekeep-alive是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中;使用keep-alive包裹动
态组件时,会缓存不活动的组件实例,而不是销毁它们。

使用场景:
用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面,我们希望:列表页面可以保留用户的筛选(或选中)状态。
keep-alive就是用来解决这种场景。当然keep-alive不仅仅是能够保存页面/组件的状态这么简单,它还可以避免组件反复创建和渲染,有效提升系统性能。总的来说,keep-alive用于保存组件的渲染状态。

 
34、懒加载和预加载的区别1)概念:
懒加载也叫延迟加载:JS图片延迟加载,延迟加载图片或符合某些条件时才加载某些图片。
预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。
2)区别:
两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。
35、高度塌陷的产生条件和解决方法父元素高度自适应,子元素 float 后,造成父元素高度为0,称为高度塌陷问题。
方案一:给父元素一个固定的高度
缺点:给父元素固定高度违背了高度自适应的原则,不够灵活,不推荐使用。
方案二:给父元素添加属性 overflow: hidden;
优点:浏览器支持好,简单;
缺点:当子元素有定位属性时,设置 overflow: hidden; 容器以外的部分会被裁剪掉
方案三:在子元素的末尾添加一个空的 div ,并设置下方样式
div{clear: both;height: 0;overflow: hidden;}
优点:所有浏览器都支持,并且容器溢出不会被裁剪;
缺点:在页面中添加无意义的div,容易造成代码冗余。
方案四:万能清除浮动法
在父元素中内容的最后添加一个伪元素来实现第三种方案的功能,具体设置样式如下:
父元素:after{content: "";clear: both;display: block;}
优点:不会造成代码冗余,剩余代码性能优化,推荐使用。
36、进程间通信方式?(操作系统问题)1、管道,匿名管道,命名管道
2、信号
3、信号量
4、消息队列
5、共享内存
6、socket
37.vue
38、js判断变量是数组还是对象1、使用typeof加length属性。数组有length属性,object没有
2、使用instanceof alert( a instanceof Array ); // true
3、使用Array.isArray
4、Object.prototype.toString.call(obj) === '[object Array]';
5、使用constructor属性
39、描述堆和栈基本数据类型变量都维护在栈区,基本数据类型的值保存在栈区。
引用数据类型的引用地址保存在栈区,值保存在堆区。
40、实现深拷贝实现深拷贝的方法
1.JSON.parse(JSON.stringify())
2.函数库lodash的_.cloneDeep方法
3.jQuery.extend()方法
4.手写递归方法
5、Object.assign()实现深拷贝
6、使用拓展运算符...

 
41、浏览器缓存机制HTTP 缓存即是浏览器第一次想一个服务器发起 HTTP 请求后,服务器会返回请求的资源,并且在响应头中添加一些有关缓存的字段如: cache - control , expires , last - modifed , ETag , Date ,等,之后浏览器再向该服务器请求资源就可以视情况使用强缓存和协商缓存,
缓存分为两种,强缓存和协商缓存,根据响应的header内容来决定
强缓存:浏览器直接从本地缓存中获取数据,不与服务器进行交互,
协商缓存:浏览器发送请求到服务器,服务器判断是否可使用本地缓存
强缓存相关字段有expires,cache-control,如果cache-control和expires同时存在,cache-control的优先级高于expires
协商缓存相关字段有Last-Modifed/If-Modified-Since,Etag/If-None-Match
42、做网页时,浏览器兼容性问题怎么解决?同浏览器对HTML标记所具有的内外边距属性具有不同的定义。

因此如果想消除这种差距,应该在相应的CSS部分加入以下CSS代码:

*{margin:0px;padding:0px;}

借于此,所有标记的内外边距被统一起来。
优先级问题:

对于同一标记属性所给定的值,有不同的优先级。其中优先级最高的是内联代码,其实是页内CSS,接下来是浏览器默认设置,最后才是外部CSS所做的限制。

Margin不一致的问题:

当有多张图片需要排在一行时,通常使用“Float:Left”来实现,这样一来,浏览器就存在兼容性问题。导致图片与后面的内容存在margin不一致的问题。对此一种解决方法就是给图片添加“Display:inline”项即可。

DIV居中问题:

通常会利用“vertical-align:middle”来实现,这对于搜狗浏览器来说,是正常的,但是对于IE浏览器来说,却并没有效果。对此,一种较好的解决方法是:将文字的行高设置与DIV一样时即可解决问题。

内外边框合并问题。通常情况下,对于两个相关DIV块,相邻时采用外边距合并原则,其结果只最两个DIV块中Margin最大值做为两个DIV之间的间距。包含的两个DIV之间的间距也遵行同样的规则。
43、token过期怎么办token已过期代表证书等过期的意思。需要重新获取code,然后得到access_token,即要重新调用授权界面,需要用refreshtoken刷新accesstoken,如果刷新取到了新的accesstoken、refreshtoken、expirein,需要用这些新的去替换掉关联表中的数据,建议每次登录的时候都用refreshtoken。
44、JavaScript中Map和ForEach的区别forEach()返回值是undefined,不可以链式调用,forEach()允许callback更改原始数组的元素。forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来。

map()返回一个新数组,原数组不会改变。map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。
没有办法终止或者跳出forEach()循环,除非抛出异常,所以想执行一个数组是否满足什么条件,返回布尔值,
可以用一般的for循环实现,或者用Array.every()或者Array.some();
46、v-if和v-show区别1、v-if显示隐藏是将dom元素整个添加或删除
2、v-show:简单的切换css样式,为该元素添加css–display:none,dom元素还在
如果要频繁切换节点,使用v-show,不需要频繁使用,用v-if
v-if 具有dom开销,即会创建、删除节点
v-show 不具有dom开销,隐藏显示节点
47、Vue数据劫持如何实现?在Vue中其实就是通过Object.defineProperty来劫持对象属性的setter和getter操作,并“种下”一个监听器,当数据
发生变化的时候发出通知。
https://wwwblogs/webcabana/p/11077628.html
所谓的双向绑定其实就是,ui或者数据有一方做了修改,那么另外一个也会随着改变。
observerObject主要做的就是使用Object.defineProperty去监听传入的属性,如果target是一个对象的话,就递归执行observer,确保data中所有的对象中的所以属性都能够被监听到。当我们set的时候,去执行renderView(执行视图渲染相关逻辑)。
Object.defineProperty的问题在于,只能够作用在对象上,那么vue中,对数组是怎么实现数据劫持的呢? 只需要修改数组的原型方法,往这些方法里添加一些视图渲染的操作。
48、简述 JavaScript 的事件捕获和事件冒泡事件冒泡:
IE 事件流被称为事件冒泡,这是因为事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没
有那么具体的元素(文档)。
事件捕获:事件捕获的意思是最不具体的节点应该最先收到事件,而最具体的节点应该最后收到事件。事件捕获实际上是为了在事件到达最终目标前拦截事件。
57.事件委托让利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行
事件委托的原理:
事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
49、同源策略同源策略,它是由Netscape提出的一个著名的安全策略。
当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面
当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,
即检查是否同源,只有和百度同源的脚本才会被执行。 [1]
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收
DOM事件流事件流又称为事件传播,DOM2级事件规定的事件流包括三个阶段:事件捕获阶段(capture phase)、处于目标阶段(target phase)和事件冒泡阶段(bubbling phase)

  首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件,最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应
50、数组转换成字符串Array 对象的数组与字符串相互转换方法 数组方法 说明
toString() 将数组转换成一个字符串
toLocalString() 把数组转换成本地约定的字符串
join() 将数组元素连接起来以构建一个字符串
51、数组去重Array.from(new Set(1,1,2,2,2,2,5,4,5,));
let arr = [...new Set(1,1,2,2,2,2,5,4,5,)]1、for双重循环所要去重的数组,删除重复的选项,返回修改后的数组
2、新建数组,for双重循环,外层是所要去重的数组,内层是新建的唯一的数组,如果该项不在新数组内则添加进去,最终返回新数组。
3、新建数组,for外循环+indexOf/includes,循环所要去重的数组,再用indexOf/includes判断该项是否在新数组中存在,如果该项不在新数组内则添加进去,最终返回新数组。
4、数组sort排序 + 相邻元素对比法
5、新建数组,filter + indexOf/includes
6、使用es6的new Set(数组),返回去重后的类数组,再用Array.from(类数组)转化为真正的数组。(Array.from()方法是浅拷贝类数组,返回一个真正的数组)
52、v-for的key属性的作用key属性可以用来提升v-for渲染的效率!,vue不会去改变原有的元素和数据,而是创建新的元素然后把新的数据渲染进去
在使用v-for的时候,vue里面需要我们给元素添加一个key属性,这个key属性必须是唯一的标识。给key赋值的内容不能是可变的

1. 在写v-for的时候,都需要给元素加上一个key属性
2. key的主要作用就是用来提高渲染性能的!
3.key属性可以避免数据混乱的情况出现 (如果元素中包含了有临时数据的元素,如果不用key就会产生数据混乱)
53、html/jsp 网页中url href src 三个属性有什么本质上
的区别?
url不是属性,src和href是属性,src用于替换当前元素,href用于在当前文档和引用资源之间确立联系,也就是说src引用的
路径是img自己的路径,href引用的路径是要跳转到的地方。
54、实现响应式布局1、通过em、rem来实现响应式布局
2、flex弹性盒模型
3、媒体查询
4、使用百分比布局
5、通过vw/vh来实现自适应
响应式布局响应式布局指的是同一页面在不同屏幕尺寸下有不同的布局。传统的开发方式是PC端开发一套,手机端再开发一套,而使用响应式布局只要开发一套就够,缺点就是CSS比较重。
https://www.luding333/7488.html
55.vue中data为什么是函数?组件是一个可复用的实例,当你引用一个组件的时候,组件里的data是一个普通的对象,所有用到这个组件的都引用的同一个data,就会造成数据污染。
不使用return包裹的数据会在项目的全局可见,会造成变量污染;使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
当一个组件被定义, data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
为什么data函数需要返回一个返回值,返回值还是对象,不
能是数组吗?
Vue通过es5的Object.definePerproty属性对一个对象进行getter和setter设置,
而data选项是作为Vue深入响应式核心的选项
56.px,em,rem,vh的区别px就是pixel像素的缩写,相对长度单位,网页设计常用的基本单位。像素px是相对于显示器屏幕分辨率而言的
em是相对长度单位。相对于当前对象内文本的字体尺寸(参考物是父元素的font-size)如当前父元素的字体尺寸未设置,则
相对于浏览器的默认字体尺寸

rem是CSS3新增的一个相对单位,rem是相对于HTML根元素的字体大小(font-size)来计算的长度单位如果你没有设置html
的字体大小,就会以浏览器默认字体大小,一般是16px

vw是相对视口(viewport)的宽度而定的,长度等于视口宽度的1/100,假如浏览器的宽度为200px,那么1vw就等于2px(200px/100)

vh是相对视口(viewport)的高度而定的,长度等于视口高度的1/100,假如浏览器的高度为500px,那么1vh就等于5px(500px/100)
58.用什么方式创建的项目vue-cli脚手架
59.webpack的基础配置webpack基础配置 - 冰凌哒雪花 - 博客园
60.webpack的loadderloader:是webpack用来预处理模块的,在一个模块被引入之前,会预先使用loader处理模块的内容
默认webpack只会处理js代码,所以当我们想要去打包其他内容时,让webpack处理其他类型的内容,就要使用相应的loader
webpack常用的loader
样式:style-loader、css-loader、less-loader、sass-loader等
文件:raw-loader、file-loader 、url-loader等
编译:babel-loader、coffee-loader 、ts-loader等
校验测试:mocha-loader、jshint-loader 、eslint-loader等
https://zhuanlan.zhihu/p/28245984
61.怎么用em、rem实现响应式布局
62.原型链每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这
个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我
们平时所说的原型链的概念
• 特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变,当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象
63.vue-router的原理vue-router通过hash与History interface两种方式实现前端路由,更新视图但不重新请求页面”是前端路由原理的核心之一,
目前在浏览器环境中这一功能的实现主要有两种方式

hash ---- 利用URL中的hash(“#”)
利用History interface在 HTML5中新增的方法

https://wwwblogs/gaosirs/p/10606266.html
64、描述箭头函数以及它的this,箭头函数和普通函数的区别*箭头函数的 this 永远指向其上下文的 this ,指向声明剪头函数的外部函数的this,任何方法都改变不了其指向,如 call() , bind() , apply()
*普通函数的this指向调用它的那个对象。
*也可以说箭头函数本身没有this,但是它在声明时可以捕获其所在上下文的this供自己使用。
*箭头函数在全局作用域声明,所以它捕获全局作用域中的this,this指向window对象。
*普通函数可以有匿名函数,也可以有具体名函数,但是箭头函数都是匿名函数。
65、栈和队列的区别队列(Queue):是限定只能在表的一端进行插入和在另一端进行删除操作的线性表;
栈(Stack):是限定只能在表的一端进行插入和删除操作的线性表。
区别如下:
一、规则不同
1. 队列:先进先出(First In First Out)FIFO
2. 栈:先进后出(First In Last Out )FILO

二、对插入和删除操作的限定不同
1. 队列:只能在表的一端进行插入,并在表的另一端进行删除;
2. 栈:只能在表的一端插入和删除。

三、遍历数据速度不同
1. 队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快;
2. 栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。
66.http状态码200 OK:表示从客户端发送给服务器的请求被正常处理并返回;

204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回);

206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。

3xx (5种)

301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;

302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;

301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)

303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;

302与303的区别:后者明确表示客户端应当采用GET方式获取资源

304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码;

307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况);

4xx (4种)

400 Bad Request:表示请求报文中存在语法错误;

401 Unauthorized:未经许可,需要通过HTTP认证;

403 Forbidden:服务器拒绝该次访问(访问权限出现问题)

404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;

5xx (2种)

500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时;

503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求;
67.var let const的区别*var 声明的变量属于函数作用域,let 和 const 声明的变量属于块级作用域;
*var 存在变量提升现象,而 let 和 const 没有此类现象;
*var 变量可以重复声明,而在同一个块级作用域,let 变量不能重新声明,const 变量不能修改。
*var 和 let 用以声明变量,const 用于声明只读的常量;
68.组件传参(组件之间通信的方式)父传子:父组件通过props向下传递数据给子组件
子传父:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。给子组件需要传值的标签绑定点击事件,在响应该点击事件的函数中使用$emit来触发一个自定义事件,并传递一个参数;在父组件中的子标签中监听该自定义事件并添加一个响应该事件的处理方法
兄弟传:1.创建公共的vue对象(var bridge = new Vue());要传送的兄弟组件绑定点击事件,在响应该点击事件的函数中使用brige.$emit来触发一个自定义事件,被传送的兄弟组件在mounted()通过bridge.$on接收
vuex也可以实现组件通信

https://segmentfault/a/1190000019208626
69、简述vue和jQuery的区别?jquery是DOM驱动框架,没有摆脱DOM操作,只是将原生js语法做了封装
Vue是数据驱动框架,实现了Dom操作

jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:$("lable").val();,它还是依赖DOM元素的值。
Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。
70、对mvvm的理解MVVM 是 Model-View-ViewModel 的缩写,它是一种软件架构风格
Model:数据模型,数据和业务逻辑都在Model层中定义
View:表UI视图,负责数据的展示(用于渲染数据)
ViewModel:视图模型,其实本质上就是 Vue 实例。就是与界面(view)对应的Model。因为,数据库结构往往是不能直接跟界面控件一一对应上的,所以,需要再定义一个数据对象专门对应view上的控件。而ViewModel的职责就是把model对象封装成可以显示和接受输入的界面数据对象。

Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Model中同步。。
简单的说,ViewModel就是View与Model的连接器,View与Model通过ViewModel实现双向绑定。
71、http协议和tcp协议的区别
72.promise的APIPromise.prototype.then():它的作用是为 Promise 实例添加状态改变时的回调函数(then方法返回的是一个新的Promise实例)

Promise.prototype.catch():用于指定发生错误时的回调函数。Promise 对象后面要跟catch()方法,这样可以处理 Promise 内部发生的错误。catch()方法返回的还是一个 Promise 对象,因此后面还可以接着调用then()方法。

Promise.prototype.finally():用于指定不管 Promise 对象最后状态如何,都会执行的操作。finally本质上是then方法的特例,它的的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

Promise.all():Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]); Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实 例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。Promise.all()方法只适合所有异步操作都成功的情况,如果有一个操作失败,就无法满足要求。

Promise.race():Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

Promise.allSettled():用来确定一组异步操作是否都结束了(不管成功或失败),接受一个数组作为参数,数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。

Promise.any():该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。不会因为某个 Promise 变成rejected状态而结束,必须等到所有参数 Promise 变成rejected状态才会结束。

Promise.resolve():将现有对象转为 Promise 对象
Promise.resolve()方法的参数分成四种情况。
(1)参数是一个 Promise 实例
(2)参数是一个thenable对象
(3)参数不是具有then()方法的对象,或根本就不是对象
(4)不带有任何参数

Promise.reject():会返回一个新的 Promise 实例,该实例的状态为rejected。
Promise.try():


https://es6.ruanyifeng/#docs/promise#Promise-prototype-then
1.vue双向数据绑定原理是什么
答:通过数据解劫持基于发布订阅者模式,当数据发生改变发布者通知订阅者改变视图
2.v-for key的值作用是什么(回答不怎么好就不说了) 但是我回答里有说到diff算法。
他的diff算法是怎么实现的,问到这里我就直接懵了。当时我心里就想我一个实习生要问的这么深吗
call(),apply(),bind()的区别fn.call(obj, arg1, arg2, ...),调用一个函数, 具有一个指定的this值和分别地提供的参数(参数的列表)。
fn.apply(obj, [argsArray]),调用一个函数,具有一个指定的this值,以及作为一个数组(或类数组对象)提供的参数。
var ss=函数.bind(对象,arg1,arg2,....)而bind调用之后是返回原函数,需要再调用一次才行。
fn.bind(obj,"a","b")();但是由于bind返回的仍然是一个函数,所以我们还可以在调用的时候再进行传参。fn.bind(obj)("a","b");
三者的相同之处:
1、都是用来改变函数的this对象的指向的。
2、第一个参数都是this要指向的对象。
3、都可以利用后续参数传参。
new做了什么1、创建一个空对象obj
2、设置原型链。 让obj的__proto__属性,指向函数的原型
3、让函数中的this指向obj。并且执行函数体 Function.call(obj);
4、判断函数返回值的内容
如果返回的是对象,此时就不做操作了。直到最后将该对象赋值给一个变量。
如果返回的是一个值,此时返回obj,然后直到最后的赋值操作
什么是BFC?BFC的形成条件BFC(block formatting context)块级格式化上下文 定义:是web页面对盒模型采用不同的渲染模式,形成隔离的独立容器。
BFC的形成条件
1、根元素。html标签
2、浮动元素float。除none
3、定位元素position。absolute fixed
4、display。inline-block table-cell table-caption等
5、overflow。除visible。 包含hidden auto scroll
那么BFC能解决哪些问题呢?
BFC的作用
1、解决margin重叠。两盒子包裹一层外盒子,外盒子设置bfc。
2、解决margin塌陷。子元素的margin-top会带着父元素一起移动,给父元素设置bfc。
3、解决浮动的高度塌陷。给父盒子设置bfc。
4、解决浮动元素覆盖文档流。给文档流元素设置bfc。
CORS
ajax实现过程1.创建XMLHttpRequest对象,也就是创建一个异步调用对象.
2.创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
3.设置响应HTTP请求状态变化的函数.
4.发送HTTP请求.
5.获取异步调用返回的数据.
6.使用JavaScript和DOM实现局部刷新.
https://blog.csdn/qq_29569183/article/details/79259889
为什么选择前端
三栏布局
发布订阅者模式在现在的发布订阅模式中,称为发布者的消息发送者不会将消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者。
promise
什么是ajax?ajax的同步异步?ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
异步:异步处理是客户通过事件触发ajax,向服务器发送请求,在这个期间无论服务器有没有响应,客户端的其他代码一样可以运行。
同步:同步处理是客户通过事件触发ajax,向服务器发送请求,在这个期间客户端不能做任何处理。当ajax执行完毕才会继续执行其他代码。
优化网页速度的方法?1.优化图片资源的格式和大小
2.开启网络压缩
3.使用浏览器缓存
4.减少重定向请求
5.使用CDN存储静态资源
6.减少DNS查询次数
7.压缩css和 js 内容
css+div开发web页面的优势有那些?1.表现与结构分离
2.提高搜索引擎的索引效率
3.利于维护和改版
路由跳转传参数(路由传参)1.传递:this.$router.push({name:'路由name',params:{search:value}})
获取:this.$route.params.search
2.通过path携带的参数 传递:this.$router.push({ path: '路由url'+id})
获取:this.$route.params.id 注意此方法使用时需在路由path中配置 /:id {path: 'myadmexp/details/:id'}
3.通过query来传递参数,使用此方法传递的参数会出现在url地址中
传递:this.$router.push({ name:'name' ,query:{id:code,id2:code2}});
获取:this.$route.query.id;
在不使用中间变量的情况下 使用什么方法来交换两个
变量的值

-----解构赋值
let a = 1;
let b = 2;
[a,b] = [b,a]
console.log(a,b);//2 1
讲一下Set和Map数据类型(es6里面的)
Set和数组有什么区别set没有索引值,数组有索引值
set中的元素不允许重复,数组可以存在重复的值
在项目中父子组件之间的生命周期的顺序?父子组件的生命周期中,首先走父组件的生命周期,当父组件的生命周期走完beforeMount(挂在前)这个函数时就会走子组件的生命周期,当子组件挂载完成后(执行完mounted)父组件在挂载dom节点。
js中的this指向avaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
1.在方法中,this 表示该方法所属的对象。
2.如果单独使用,this 表示全局对象。
3.在函数中,this 表示全局对象。
4.在函数中,在严格模式下,this 是未定义的(undefined)。
5.在事件中,this 表示接收事件的元素。
6.类似 call() 和 apply() 方法可以将 this 引用到任何对象。
高级前端面试题 js篇 - DAVENEE - 博客园
webpack:webpack 面试题 - DAVENEE - 博客园
字符串方法字符串方法 - DAVENEE - 博客园
Vue实现数据双向绑定的原理:Object.defineProperty()

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
双向数据绑定的具体应用场景双向绑定的优缺点就是单向绑定的镜像了。优点是在表单交互较多的场景下,会简化大量业务无关的代码。缺点就是由于都是“暗箱操作”,我们无法追踪局部状态的变化(虽然大部分情况下我们并不关心),潜在的行为太多也增加了出错时 debug 的难度。同时由于组件数据变化来源入口变得可能不止一个,新手玩家很容易将数据流转方向弄得紊乱,如果再缺乏一些“管制”手段,最后就很容易因为一处错误操作造成应用雪崩。

UI控件 中(通常是类表单操作),我会使用双向的方式绑定数据;
vuevue基础总结1 - DAVENEE - 博客园
浏览器解析url后执行过程1.用户输入网址,浏览器发起DNS查询请求
2.建立TCP连接:浏览器通过DNS获取到web服务器真的IP地址后,便向web服务器发起tcp连接请求
3.浏览器向 web 服务器发送一个 HTTP 请求
4.发送响应数据给客户端
5.浏览器解析http response
:1)html文档解析(DOM Tree)
(2)浏览器发送获取嵌入在HTML中的对象
3)css解析(parser Render Tree)
(4)js解析

更多推荐

2021前端面试题

本文发布于:2023-06-14 09:07:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1459796.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:面试题

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!