听说成年人的自尊都是工资给的,我已经没有自尊两个多月了,哈哈哈
疫情影响很多小伙伴都被破离职了,下面整理了一些常见面试题,可以大家一起分享,程序员小白一个,如有问题,欢迎大佬们随时指点呀~~
我们也可以使用这样包含 type 属性的对象的提交方式。
最好提前在你的 store 中初始化好所有所需属性。
当需要在对象上添加新属性时,你应该
八、vue路由的钩子函数
vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消。
路由钩子分为三类: 全局的、单个路由独享的、或者组件级的
全局钩子: 主要包括beforeEach和afterEach,这类钩子主要作用于全局,一般用来判断权限,以及页面丢失时候需要执行的操作。一般写在发消息(子窗口同样可以通过该方法发送消息给父窗口)
它可用于解决以下方面的问题:
页面和其打开的新窗口的数据传递
页面与嵌套的iframe消息传递
上面三个场景的跨域数据传递
调用message事件,监听对方发送的消息
SPA需要在不刷新页面的情况下做页面更新的能力,这就需要引入前端路由,实际上,前端路由是利用了浏览器的hash或history属性。
hash :(兼容性更强)
hash (url中#后面的部分)虽然出现在 URL 中,但不会被包含在 http 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
当hash改变时,会触发hashchange事件,监听该事件,对页面进行更新。
在当前已有的 back、forward、go 基础之上,它们提供了对历史记录 修改的功能(pushState将传入url直接压入历史记录栈,replaceState将传入url替换当前历史记录栈)。
只是当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求。
pushState 设置的新的 url 可以与当前 url 一样,这样也会把记录添加到栈中;hash 设置的新值不能与原来的一样,一样的值不会触发动作将记录添加到栈中。
pushState 通过 stateObject 参数可以将任何数据类型添加到记录中;hash 只能添加短字符串。
history 在刷新页面时,如果服务器中没有相应的响应或资源,就会出现404。因此,如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
hash 模式下,仅 # 之前的内容包含在 http 请求中,对后端来说,即使没有对路由做到全面覆盖,也不会报 404。
十一、vue的内容分发
将父组件的内容放到子组件指定的位置叫做内容分发或者叫做slot(插槽)
组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力
2.多个插槽也叫具名插槽:具名插槽就是将某个名字的内容插到子组件对应名字里面去
可以实现内容不同样式不同,通过slot中的name属性绑定元素
具名插槽和匿名插槽的区别:
通过slot属性来指定, 这个slot的值必须和下面slot组件得name值对应上 如果没有匹配到 则放到匿名的插槽中
需要注意的是 相同的name值的互相替换,没有用slot指定名字所以会替换掉子组件里没有name属性的slot标签
作用插槽允许你将模板传递给插槽,而不是传递一个已呈现的元素。它被称为作用域的插槽,因为尽管模板在父范围内呈现,但它可以访问某些子数据。
当子组件做循环显示列表 或 某一部分由外部传递进来 时,则使用 作用域插槽
父组件对子组件加工处理
既可以复用子组件的slot,又可以使slot内容不一致
浅拷贝和深拷贝都只针对于像Object, Array这样的复杂对象,
区别:浅拷贝只复制对象的第一层属性、深拷贝可以对对象的属性进行递归复制
简单来说,深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。
浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。
v-text 输出的是纯文本,浏览器不会对其再进行html解析
一些静态的内容不需要编译加pre指令可以加快渲染
十四、vue双向绑定原理
十五、for循环结构遍历数组时key的作用
1)key来给每个节点做一个唯一标识
2)key的作用主要是为了高效的更新虚拟DOM,提高性能
提示:v-if和v-for不推荐一起使用,当使用的时候v-for具有比v-if更高的优先级。
到了时间点不用我们操作,自己就会触发
- vue内置的指令可能在开发的时候不够用,这时候,我们可以考虑自己自定义指令
十八、父子组件传值以及非父子组件传值
父组件向子组件传值--基本用法
子组件向父组件传值--基本用法
子组件获取到父组件中的函数值方法一:
子组件获取到父组件中的函数值方法二:
子组件向父组件传值:(在$emit('父组件中的函数名',想传的值),在父组件中的methods中的函数fn中使用传过来的值
兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
(要改变谁,在谁里面写mounted,这样通过this,就能改变谁里面的数据)
销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
如果触发事件传递值了,监听事件参数中要有(形参)与之对应
销毁事件函数,需要定义在兄弟的父亲methods中
computed里面的方法不是通过事件去触发的,而是当属性(必须是data中的属性)发生改变的时候那么当前函数就会被触发
最大的区别是,computed中有缓存,相同的值会直接拿已经缓存的,提高性能,但是method没有缓存,一样的值还是会重新获取
二十、渐进增强和优雅降级之间的不同
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
1.优雅降级是从复杂的现状开始,并试图减少用户体验的供给
2.渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要
3.降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带
sessionStorage和localStorage是HTML5 Web Storage API提供的,可以方便的在web请求之间保存数据。有了本地数据,就可以避免数据在浏览器和服务器间不必要地来回传递。sessionStorage、localStorage、cookie都是在浏览器端存储的数据,其中sessionStorage的概念很特别,引入了一个“浏览器窗口”的概念。sessionStorage是在同源的同窗口(或tab)中,始终存在的数据。也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一页面,数据仍然存在。关闭窗口后,sessionStorage即被销毁。同时“独立”打开的不同窗口,即使是同一页面,sessionStorage对象也是不同的cookies会发送到服务器端。其余两个不会。
sessionStorage:用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁,是会话级别的存储。
localStorage:用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
1.使用空标签清除浮动。这种方法是在所有浮动标签后面添加一个空标签定义css clear:both.弊端就是增加了无意义标签。
3.使用after伪对象清除浮动。该方法只适用于非IE浏览器。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置height:0,否则该元素会比实际高出若干像素;二、content属性是必须的,但其值可以为空,content属性的值设为”.”,空亦是可以的。
二十三、什么是闭包,如何使用它,为什么要使用它?
包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
- 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
- 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
(关于闭包,详细了解请看[JavaScript之作用域与闭包详解]()
二十四、JavaScript宿主对象和原生对象的区别?
ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。
同样是“独立于宿主环境”。根据定义我们似乎很难分清“内置对象”与“本地对象”的区别。而ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。如此就可以理解了。内置对象是本地对象的一种。
何为“宿主对象”?主要在这个“宿主”的概念上,ECMAScript中的“宿主”当然就是我们网页的运行环境,即“操作系统”和“浏览器”。
实现的宿主环境提供的对象。所有的BOM和DOM都是宿主对象。因为其对于不同的“宿主”环境所展示的内容不同。其实说白了就是,ECMAScript官方未定义的对象都属于宿主对象,因为其未定义的对象大多数是自己通过ECMAScript程序创建的对象。
二十五、call和apply的区别是什么?
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
对于apply和call两者在作用上是相同的,但两者在参数上有以下区别:
对于第一个参数意义都一样,但对第二个参数:apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。如
二十六、==和===有什么不同?
== equality 等同,=== identity 恒等。 ==, 两边值类型不同的时候,要先进行类型转换,再比较。 ===,不做类型转换,类型不同的一定不等。
二十七、http和https有什么区别?
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时;典型的案例就是输入搜索:输入结束后n秒才进行搜索请求,n秒内又输入的内容,就重新计时。
节流:规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效; 典型的案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效。
二十九、es6的新语法你了解哪些?
ES6 推荐在函数中使用 let 定义变量
const 用来声明一个常量,但也并非一成不变的
let 和 const 只在最近的一个块中(花括号中)有效
let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。
利用let声明的变量会绑定在这个块级作用域,不会受外界的影响
这时候打印的会是tmp没有被定义过,因为花括号里的被锁死了,let又没有变量提升,所以没被定义
声明常量,常量就是值(内存地址)不能变化的量
1)声明常量时必须赋值 ,必须声明后马上赋值
2)既然是常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更改地址值
- 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
- 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
- 使用 const 声明的是常量,声明时候必须要给定值,在后面出现的代码中不能再修改该常量的值
解构赋值是ES6中推出的一种高效、简洁的赋值方法
ES6中提供了用反引号`来创建字符串,里面可包含${…}等
- Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的 deferred 对象。当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promise模式
使你能够将字面量对象展开为多个元素
async 函数返回的是一个 Promise 对象,所以在最外层不能用 await 获取其返回值的情况下,我们当然应该用原来的方式:then()
链来处理这个 Promise 对象,就像这样
await 可以用于等待一个 async 函数的返回值
如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
看到上面的阻塞一词,心慌了吧……放心,这就是 await 必须用在 async 函数中的原因。async 函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。
它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成 Set 数据结构
对象是键值对集合,和 JSON 对象类似,但是 key 不仅可以是字符串还可以是对象
三十、get和post的区别?
其实,GET和POST本质上两者没有任何区别。他们都是HTTP协议中的请求方法:底层实现都是基于TCP/IP协议。所谓区别,只是浏览器厂家根据约定,做得限制不同而已。
(1)使用Get请求时,参数在URL中显示,而使用Post请求,则不会显示出来;
(2)Post传输的数据量大,可以达到2M,而Get方法由于受到URL长度的限制,只能传递大约1024字节.
(3)Get请求请求需注意缓存问题,Post请求不需担心这个问题;
(5)发送请求时,因为Get请求的参数都在url里,所以send函数发送的参数为null,而Post请求在使用send方法时,却需赋予其参数;
(6)GET方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全问题。而POST方式相对来说就可以避免这些问题。
最后推荐一篇关于面试的文章,个人觉得写的很好?