面试问题(连更中............)

一 .  特性

H5新特性:

1、拖拽释放(drag and drop)API

2、语义化更好的内容标签(header footer nav aside article section)

3、音频、视频(audio video)API

4、画布(Canvas)API

5、地理(Geolocation)API

6、localstorage 和 sessionstorage 缓存方式

7、表单控件(calendar date time email ul search)

8、新技术(webworker websocket Geolocation)

c3新特性

  1. 选择器
  2. 背景和边框
  3. 文本效果
  4. 2D/3D 转换 — 变形(transform)、过渡(transtion)、动画(animation)

es6的新特性

  • 模板字符串
  • promise语法
  • 三点语法
  • 箭头函数
  • let const
  • for...of 和 for...in

----------------------------------------------------------------------------------------------------------

二 . vue 原型 闭包 作用域 跨域 冒泡 路由守卫 ajax pronise vuex

vue2

beforeCreate(创建前)

created(创建后)

beforeMount(载入前),(挂载)

mounted(载入后)

beforeUpdate(更新前)

updated(更新后)

beforeDestroy(销毁前)

destroyed(销毁后)

vue3

setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method onBeforeMount() : 组件挂载到节点上之前执行的函数。 onMounted() : 组件挂载完成后执行的函数。 onBeforeUpdate(): 组件更新之前执行的函数。 onUpdated(): 组件更新完成之后执行的函数。 onBeforeUnmount(): 组件卸载之前执行的函数。 onUnmounted(): 组件卸载完成后执行的函数 onActivated(): 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行。 onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行。 onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数。

vue2 和 vue3 的区别

升级v3是因为 v2有一些基础bug 例如数据丢失等 但是 v3就解决了这个问题 v3利用了双向数据绑定 数值变化页面就该变

v2 和 v3 的 api 不一样 v2的api是选择式的 v3是组合式的 例如 setup就是组合的

v2 和 v3 的生命周期也不太一样

v2 和 v3 的双向绑定也不太一样,v2采用的是object.definepropty()数据劫持订阅发布获取的 v3采用的是 proxy 数据代理

v3也没有this指向 如果需要的话 可以在 setup 进行定义

LESS与SASS的区别

sass和less主要区别:在于实现方式 less是基于JavaScript的在客户端处理 所以安装的时候用npm,sass是基于ruby所以在服务器处理。

常见兼容性问题?


(1)浏览器兼容问题一:不同浏览器的标签默认的外补丁和内补丁不同 问题症状:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大。 碰到频率:100% 解决方案:CSS里 {margin:0;padding:0;} 备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符来设置各个标签的内外补丁是0。

(2)浏览器兼容问题二:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大 问题症状:常见症状是IE6中后面的一块被顶到下一行 碰到频率:90%(稍微复杂点的页面都会碰到,float布局最常见的浏览器兼容问题) 解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性 备注:我们最常用的就是div+CSS布局了,而div就是一个典型的块属性标签,横向布局的时候我们通常都是用div float实现的,横向的间距设置如果用margin实现,这就是一个必然会碰到的兼容性问题。

(3)浏览器兼容问题三:设置较小高度标签(一般小于10px),在IE6,IE7,遨游中高度超出自己设置高度 问题症状:IE6、7和遨游里这个标签的高度不受控制,超出自己设置的高度 碰到频率:60% 解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。 备注:这种情况一般出现在我们设置小圆角背景的标签里。出现这个问题的原因是IE8之前的浏览器都会给标签一个最小默认的行高的高度。即使你的标签是空的,这个标签的高度还是会达到默认的行高。

(4)浏览器兼容问题四:行内属性标签,设置display:block后采用float布局,又有横行的margin的情况,IE6间距bug 问题症状:IE6里的间距比超过设置的间距 碰到几率:20% 解决方案 : 在display:block;后面加入display:inline;display:table; 备注:行内属性标签,为了设置宽高,我们需要设置display:block;(除了input标签比较特殊)。在用float布局并有横向的margin后,在IE6下,他就具有了块属性float后的横向margin的bug。不过因为它本身就是行内属性标签,所以我们再加上display:inline的话,它的高宽就不可设了。这时候我们还需要在display:inline后面加入display:talbe。

(5) 浏览器兼容问题五:图片默认有间距 问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,加了问题一中提到的通配符也不起作用。 碰到几率:20% 解决方案:使用float属性为img布局 备注 : 因为img标签是行内属性标签,所以只要不超出容器宽度,img标签都会排在一行里,但是部分浏览器的img标签之间会有个间距。去掉这个间距使用float是正道。(使用负margin,虽然能解决,但负margin本身就是容易引起浏览器兼容问题的用法,所以我禁止他们使用)

(6) 浏览器兼容问题六:标签最低高度设置min-height不兼容 问题症状:因为min-height本身就是一个不兼容的CSS属性,所以设置min-height时不能很好的被各个浏览器兼容 碰到几率:5% 解决方案:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !important; height:200px; overflow:visible;} 备注:在B/S系统前端开时,有很多情况下我们又这种需求。当内容小于一个值(如300px)时。容器的高度为300px;当内容高度大于这个值时,容器高度被撑高,而不是出现滚动条。这时候我们就会面临这个兼容性问题。

(7)浏览器兼容问题七:透明度的兼容CSS设置 一般在ie中用的是filter:alpha(opacity=0);这个属性来设置div或者是块级元素的透明度,而在firefox中,一般就是直接使用opacity:0,对于兼容的,一般的做法就是在书写css样式的将2个都写上就行,就能实现兼容

移动端兼容问题
一、在移动端使用click事件有300ms延迟的问题

  1. 禁止双击缩放===》meta:user-scalabel=no
  2. fastclick.js

HTTP的请求方式

get 请求速度快 但是安全性不是很好 可以通过路径查看携带的数据内容

post 请求速度慢 但是安全性相对好很多 请求的时候自带乱码隐藏

前端优化

闭包(iife自执行函数)()

简单的来说就是函数嵌套函数 就是闭包

严格来讲就是内部可以访问外部数据,外部无法访问内部数据变量,从而形成了一个闭环就是闭包,

闭包缺点

占内存 消耗设备性能,造成内存外泄 还会造成很多废弃垃圾 我们可以定期检查删除,也可以运行之后将多余的数据进行删除

大量使用闭包,造成内存占用空间增大,有内存泄露的风险

如何避免闭包引起的内存泄漏 

在退出函数之前,将不使用的局部变量全部删除。(使用结束后释放内存)

原型

每创建一个构造函数 都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。

原型链

当访问一个对象的属性时, 每一个对象数据类型(普通的对象、实例、prototype......)也天生自带一个属性__proto__,如果上一级没有就继续向上进行查找,这个过程相当一个链条一样 所以叫原型链  原型链查找到最后就是 空 null (Object.prototype.__proto__ == null)

原型链最终的指向是Object的prototype, 而Object中的__proto__是null 如果原型指向改变了, 那么就应该在原型改变指向之后添加原型方法”

全局作用域 和 局部作用域

全局作用域 创建在开始,任何函数如果需要都可以调用

局部作用 创建在函数里边 只有自己可以用 其他人无权调取使用

作用域链

变量取值会到创建这个变量的函数的作用域中取值,如果找不到,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。作用域最顶层是window ,

原型链和作用域链的区别

原型链

当访问一个对象的属性时, 会在这个对象的属性上去找,如果没有找到就会去这个对象的--proto-- 上去找,即构造函数prototype 上找,如果没有会一直在--proto-- 上找,直到最顶层,不到即为undefined 。这样一层一层地向上,就彷佛一条链子串起来,所以就叫原型链。

作用域链

变量取值会到创建这个变量的函数的作用域中取值,如果找不到,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。作用域最顶层是window ,

区别就是

作用域链是相对于变量而言, 原型是相对于属性而言

作用域最顶层是window ,原型链最顶层是Object

url 哪些地方不同算作跨域?

  • 协议
  • 域名
  • 端口

解决跨域问题

同源策略

使用jsonp 但是只能处理get的请求 像post put patch 等都不能处理

CORS

代理服务器

同源策略

同源: 协议, 域名, 端口, 三者都相同

ajax请求时, 浏览器要求当前网页和Server必须同源(安全), 否则会抛出跨域的错误

前端常见的跨域解决方案?

通过jsonp

通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。

jsonp缺点:只能实现get一种请求。

location.hash + iframe跨域

实现原理: a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。

跨域资源共享(CORS)

普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置

nginx反向代理接口跨域

实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录

WebSocket协议跨域

WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现

事件冒泡与事件委托

1) 事件冒泡的流程

基于DOM树形结构事件在目标元素上处理后, 会由内向外(上)逐层传递给所有外层元素处理

应用场景: 事件代理/委托/委派

2) 事件委托

减少内存占用(事件监听回调从n变为1) event.target 动态添加的内部元素也能响应

不要滥用

target: 发生只的的目标元素

currentTarget: 绑定监听的当前元素

Promise

Promise 可以将回调变成链式调用写法,流程更加清晰,代码更加优雅。

简单归纳下 Promise:三个状态、两个过程、一个方法,快速记忆方法:3-2-1

三个状态:pending、fulfilled、rejected

两个过程:

  • pending→fulfilled(resolve)
  • pending→rejected(reject)

一个方法:then

1. 链式操作
.then字面意思就是上一步执行完了,执行下一步,这是 Promise 对象的方法,非 Promise 对象没有.then 方法。
要使用链式操作,必须保证每个.then的都是一个Promise对象,所以处理完异步操作的回调函数后,应return 一个 新的 Promise,这样接下来的.then才是return对象的回调函数

当然还有其他概念,如catch、 Promise.all/race,这里就不展开了。

async/await与promise的关系 async/await是promise 的语法糖

async/await是消灭异步回调的终极武器

作用: 简化promise对象的使用, 不用再使用then/catch来指定回调函数

它和Promise并不互斥, 两者相辅相成执行async函数, 返回promise对象await相当于promise的then

try...catch可捕获异常, 相当于promise的catch

先并行请求2个接口后,再请求第3个接口,如何处理?

使用Promise.all()方法,将两个promise传入all方法,拿到异步结果再请求第三个

明明知道的语法,面试官一问我偏偏就是跟实际场景联系不到一块,具体代码

对vuex的理解

Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。最后,根据State的变化,渲染到视图上。

各模块在流程中的功能:

Vue Components:Vue组件。HTML页面上,负责接收用户操作等交互行为,执行dispatch方法触发对应action进行回应。

dispatch:操作行为触发方法,是唯一能执行action的方法。

actions:操作行为处理模块,由组件中的$store.dispatch('action 名称', data1)来触发。然后由commit()来触发mutation的调用 , 间接更新 state。可以定义异步函数,并在回调中提交mutation,就相当于异步更新了state中的字段 像一个装饰器,包裹mutations,使之可以异步。

commit:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。

mutations:状态改变操作方法,由actions中的commit('mutation 名称')来触发。是Vuex修改state的唯一推荐方法。该方法只能进行同步操作,且方法名只能全局唯一。 提交更改数据的方法,同步

state:state中存放页面共享的状态字段 基本数据(数据源存放地)

getters:相当于当前模块state的计算属性 从基本数据派生出来的数据

modules => 模块化Vuex

ajax

一般请求: 浏览器一般会直接显示响应体数据, 也就是我们常说的刷新/跳转页面

ajax请求: 浏览器(ajax引擎)不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应

相关数据

Axios是什么? 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术

Axios 是一个基于 promise 的 HTTP 库,简单的讲就是可以发送get、post请求。

ajax开发模式:页面将用户的操作通过ajax引擎与服务器进行通信,将返回的结果给ajax引擎,然后ajax将数据插入指定位置。

ajax数据请求

我们会有后端 接口 文档 后端在文档中定义好请求方式 我们 post 、get 请求即可 进行数据请求

3.2 axios特点

  1. 基于promise的异步ajax请求库
  2. 浏览器端/node端都可以使用
  3. 支持请求/响应拦截器
  4. 支持请求取消
  5. 请求/响应数据转换
  6. 批量发送多个请求

Ajax和axios和josn的区别

Ajax是发送异步数据请求的,axios是对Ajax的二次封装,JSON是数据的格式

ajax axios jsonp 的区别

1、jsonp是一种可以解决跨域问题的方式,就是通过动态创建script标签用src引入外部文件实现跨域,script加载实际上就是一个get请求,并不能实现post请求。(其他实现跨域的方法有:iframe,window.name,postMessage,CORS...)

2、ajax是一种技术,ajax技术包含了get和post请求的,但是它仅仅是一种获取数据的技术,不能直接实现跨域,只有后台服务器配置好Access-Control-Allow-Origin,才可以实现请求的跨域。

3、我们平时用的都是经过juery封装好的ajax,而不是原生的。这个封装好的$.ajax也有封装了jsonp的方式,只需自身配置好dataType:'jsonp'就能够利用jsonp实现get请求的跨域;如果需要实现post请求的跨域,就必须后台服务器配置好Access-Control-Allow-Origin,以及自身配置好dataType:'json'。

4、axios是通过promise实现对ajax技术的一种封装,axios是ajax,ajax不止axios。

总结:

juery的$.ajax实现get请求能跨域是因为jsonp或者因为原生ajax和服务器的配合,post请求能跨域就只能是因为原生ajax和服务器的配合。

ajax数据交互

使用Ajax 请求数据时, 被请求的URL地址, 就叫做数据接口(简称接口)。同时,每个接口必须有请求方式。

接口文档,顾名思义就是对 接口的说明文档,它是我们调用接口的依据。接口文档包含了对接口URL,参数以及输出内容的说明,我们参照接口文档就能方便的知道接口的作用,以及接口如何进行调用。

axios({ url: 'http://81.70.153.180:8081/api/getStudentList', method: 'GET', params: { // GET方式,传递参数使用params sid: 's0001', sname: '王', } }).then(res => { console.log('res', res); // res.data });

路由守卫有哪几种?

路由守卫(导航守卫)分为三种:全局守卫(3个)、路由独享守卫(1个)、组件的守卫(3个)

路由守卫的三个参数

to:要跳转到的目标路由

from:从当前哪个路由进行跳转

next:不做任何阻拦,直接通行

注意: 必须要确保 next函数 在任何给定的导航守卫中都被调用过一次。它可以出现多次,但是只能在所有的逻辑路径都不重叠的情况下,否则会报错。

全局路由守卫 全局路由守卫有三个:全局前置守卫,全局后置守卫,全局解析守卫

独享路由守卫 自己一个使用

组件内守卫

组件内守卫有个三个:路由进入之前beforeRouteEnter,路由离开时beforeRouteLeave,页面更新时beforeRouteUpdate

beforeRouteEnter(to, from, next)

1.触发进入其它路由

2.调用要离开路由的组件守卫beforeRouteLeave

3.调用全局的前置守卫beforeEach

4.在重用的组件里调用 beforeRouteUpdate

5.在路由配置里的单条路由调用 beforeEnter

6.解析异步路由组件

7.在将要进入的路由组件中调用beforeRouteEnter

8.调用全局的解析守卫beforeResolve

9.导航被确认

10.调用全局的后置钩子afterEach

11.触发 DOM 更新mounted

12.执行beforeRouteEnter守卫中传给 next的回调函数

变量提升与函数提升

变量提升(变量声明提升): 在变量定义语句之前, 就可以访问到这个变量(undefined)

函数提升(函数声明提升): 在函数定义语句之前, 就执行该函数

宏队列与微队列

宏队列: 用来保存n个宏任务的队列容器

微队列: 用来保存n个微任务的队列容器

重绘和回流

  • 重绘 :指的是当页面中的元素不脱离文档流,而简单地进行样式的变化,比如修改颜色、背景等,浏览器重新绘制样式
  • 回流 :指的是处于文档流中 DOM 的尺寸大小、位置或者某些属性发生变化时,导致浏览器重新渲染部分或全部文档的情况

1.递归简介 自己调用自己

一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量

什么是冒泡排序

是一种计算机科学领域的较简单的排序算法。

比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

为什么要进行二次封装?

api统一管理,不管接口有多少,所有的接口都可以非常清晰,容易维护。通常来说在项目开发中有三个阶段:1、开发环境2、测试环境3、生产环境

不同环境访问接口的域名是不同的,直接修改域名,这就是封装请求的原因。

vue中实现路由跳转的方式有:

1.通过router-link标签跳转;

2.通过this.$router.push ()事件跳转;

3.通过this.$router.go (n)事件跳转;

深浅拷贝

【浅拷贝】只解决了第一层的问题,

【深拷贝】这个问题通常可以通过 JSON.parse(JSON.stringify(object)) 来解决

但是该方法也是有局限性的:

会忽略 undefined会忽略 symbol不能序列化函数不能解决循环引用的对象

浅拷贝和深拷贝

简单表述:假设B复制了A,当A修改时,看B是否发生变化,如果B也跟着变化,说明这个是浅拷贝,如果B没变那就是深拷贝

1、浅拷贝方实现方式(改变地址值)
(遍历赋值,for…in)
(Object.assign())
2、深拷贝方实现方式

(遍历赋值,for…in)
(JSON.parse和JSON.stringify)

new关键字作用

在内存中创建一个新的空对象。
让this指向创建出来的空对象。
执行构造函数里面的代码,给这个空的对象添加属性和方法。
返回这个新对象(所以构造函数里面不需要return)。

let const var的区别?

var 是函数作用域 let const 是块级作用域

var有变量提升 let const 没有

var 可以被挂载 let const 不可以

var可以重复定义 let const 不可以

JS 的数据类型分类和判断

  • 1、typeof
  • 2、instanceof
  • 3、constructor
  • 4、toString

宏任务和微任务

宏任务:

setTimeout

setInterval

setImmediate

requestAnimationFrame

微任务:

process.nextTick

MutationObserver

Promise.then catch finally

值类型和引用类型

1)值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null 

2)引用类型:对象(Object)、数组(Array)、函数(Function)

值类型 vs 引用类型

除了原始类型,ES 还有引用类型,上文提到的typeof识别出来的类型中,只有object和function是引用类型,其他都是值类型。

根据 JavaScript 中的变量类型传递方式,又分为值类型和引用类型,值类型变量包括 Boolean、String、Number、Undefined、Null,引用类型包括了 Object 类的所有,如 Date、Array、Function 等。在参数传递方式上,值类型是按值传递,引用类型是按共享传递。

同步 vs 异步

同步的优点是:同步是按照顺序一个一个来,不会乱掉,更不会出现上面代码没有执行完就执行下面的代码, 缺点:是解析的速度没有异步的快;

异步的优点是:异步是接取一个任务,直接给后台,在接下一个任务,一直一直这样,谁的先读取完先执行谁的, 缺点:没有顺序 ,谁先读取完先执行谁的 ,会出现上面的代码还没出来下面的就已经出来了,会报错;

import 和require的区别

区别1:模块加载的时间

require:运行时加载
import:编译时加载(效率更高)由于是编译时加载,所以import命令会提升到整个模块的头部

区别2:模块的本质

require : CommonJs模块

import :ES6模块

区别3:严格模式

CommonJs模块和ES6模块的区别

(1)CommonJs模块默认采用非严格模式
(2)ES6 的模块自动采用严格模式,不管你有没有在模块头部加上 “use strict”;
(3)CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用


vue组件中data为什么必须是一个函数?

组件中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的data,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了。

 第一次页面加载会触发哪几个钩子?

第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

异步和单线程

单线程:

缺点: 但是串行执行的缺点在于性能,任意一个略慢的任务都会导致后续执行代码被阻塞。在计算机资源中,通常I/O与CPU计算之间是可以并行进行的。但是同步的编程模型导致的问题是,I/O的进行会让后续任务等待,这造成资源不能被更好地利用。

异步

优 :异步操作无须额外的线程负担,并且使用回调的方式进行处理,在设计良好的情况下,处理函数可以不必使用共享变量(即使无法完全不用,最起码可以减少 共享变量的数量),减少了死锁的可能。

缺 : 当然异步操作也并非完美无暇。编写异步操作的复杂程度较高,程序主要使用回调方式进行处理,与普通人的思维方式有些 出入,而且难以调试。

箭头函数

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

Set 和 Map (属于聚合数据)

1.Map是键值对,Set是值的集合,当然键和值可以是任何的值;

2.Map可以通过get方法获取值,而set不能因为它只有值;

3.都能通过迭代器进行for...of遍历;

4.Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储

5.map和set都是stl中的关联容器,map以键值对的形式存储,key=value组成pair,是一组映射关系。set只有值,可以认为只有一个数据,并且set中元素不可以重复且自动排序。

Set对象允许你存储任何类型的值,无论是原始值或者是对象引用。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Map对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。构造函数Map可以接受一个数组作为参数。

computed和watch的区别

计算属性computed:

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

侦听属性watch:

  • 不支持缓存,数据变,直接会触发相应的操作;
  • watch支持异步;
  • 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
  • 当一个属性发生变化时,需要执行对应的操作;一对多;
  • 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:

  • json数据格式 对象包数组

  • 权重 标签 类 id !important

  • 接口对接 照着接口文档

  • 文件格式的转换 file文件的拷贝和改名 file可以改变文件的格式

  • 密码加密 md5可以加密 是不可逆的,一般后端加密

ref 响应式

ref在Vue中是用来给元素或是子组件注册引用信息到父组件或是 Vue实例上,注册后的引用信息都会呈现在父组件/Vue实例的 (. r e f s ) 上 , 这 时 , 我 们 就 可 以 通 过 ( .refs) 上,这时,我们就可以通过(.refs)上,这时,我们就可以通过(.refs) 获取到引用的 DOM 对象或是子组件信息。

1、DOM本质什么?

浏览器把拿到的HTML代码,结构化一个浏览器能识别并且js可操作的一个模型而已

DOM操作——怎样添加、移除、移动、复制、创建和查找节点。

什么是BOM?

BOM:Browser Object Model 是浏览器对象模型,浏览器对象模型提供了独立与内容的、可以与浏览器窗口进行互动的对象结构,BOM由多个对象构成,其中代表浏览器窗口的window对象是BOM的顶层对象,其他对象都是该对象的子对象。

window 对象,是 JS 的最顶层对象,其他的 BOM 对象都是 window 对象的属性;

document 对象,文档对象;

location 对象,浏览器当前URL信息;

navigator 对象,浏览器本身信息;

screen 对象,客户端屏幕信息;

history 对象,浏览器访问历史信息;

事件绑定

事件绑定 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数。 所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称。 在JavaScript中,有三种常用的绑定事件的方法: 在DOM元素中直接绑定; 在JavaScript代码中绑定; 绑定事件监听函数。 在DOM中直接绑定事件

3、判断空对象

1、用JSON的stringify和parse转成字符串后,跟'{}'对比;

2、用ES6,判断Object.keys(targetObject)返回值数组的长度是否为0;

3、用ES5,判断Object.getOwnPropertyNames(targetObject)返回的数组长度是否为0;

4、如何改变this指向?

  • call/apply
let a = {
    name: 'sunq',
    fn:function(action){
        console.log(this.name + ' love ' + action);
    }
}
let b = {name:'sunLi'}

// 正常的this指向
a.fn('basketball');   // sunq love basketball
// 改变this指向,并体现call与apply的区别
a.fn.apply(b,['football']); // sunLi love football
a.fn.call(b,'football'); // sunLi love football
  • bind
// 还是上面的示例,bind也可以实现call和apply的效果。
// bind的不同之处在于bind会返回一个新的函数。如果需要传参,需要再调用该函数并传参
a.fn.bind(b)('piano'); // sunLi love piano

call、bind、apply三者的区别

三者都可以改变函数的 this 对象指向。

三者第一个参数都是 this 要指向的对象,如果如果没有这个参数或参数为 undefined 或 null,则默认指向全局 window。

三者都可以传参,但是 apply 是数组,而 call 是参数列表,且 apply 和 call 是一次性传入参数,而 bind 可以分为多次传入。

bind 是返回绑定 this 之后的函数,便于稍后调用;apply 、call 则是立即执行 。

bind()会返回一个新的函数,如果这个返回的新的函数作为构造函数创建一个新的对象,那么此时 this 不再指向传入给 bind 的第一个参数,而是指向用 new 创建的实例

是什么diff算法

比较只会在同层级进行, 不会跨层级比较

在diff比较的过程中,循环从两边向中间比较

diff 算法的在很多场景下都有应用,在 vue 中,作用于虚拟 dom 渲染成真实 dom 的新旧 VNode 节点比较

优雅降级与渐进增强的理解?

优雅降级是从复杂的现状开始,并试图减少用户体验的供给;渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。

渐进增强观点认为应该关注于内容本身,这使得渐进增强成为一种更为合理的设计范例;优雅降级观点认为应该针对那些最高级、最完善的浏览器来设计网站。

1. cookie 请求

答案就是cookie。 cookie一般保存在请求头中以一个单独的cookies字段保存 上图就是一个典型的请求头,包含一些基础header

客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。

但是 cookie 有它致命的缺点:

  • 存储量太小,只有 4KB
  • 所有 HTTP 请求都带着,会影响获取资源的效率
  • API 简单,需要封装才能用

2. localStorage 和 sessionStorage

localStorage (只存储当前 刷新就没有了)

  • 存储量增大到 5MB
  • 不会带到 HTTP 请求中
  • API 适用于数据存储 localStorage.setItem(key, value) localStorage.getItem(key)

sessionStorage (存在浏览器中 刷新不会消失)

它是根据 session 过去时间而实现,而localStorage会永久有效,应用场景不同。

例如,一些需要及时失效的重要信息放在sessionStorage中,一些不重要但是不经常设置的信息,放在 localStorage中。

节流 防抖

  • 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
  • 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

mvc和mvvm 的区别

MVVM与MVC的最大区别就是:它实现了View和Model的自动同步,也就是当Model的数据改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变数据后该数据对应View层显示会自动改变。MVVM并不是用VM完全取代了C,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。

赖加载的实现

简单来说就是一个长页面中需要展示很多图像的时候,如果在进入页面的时候一次性把所有图片加载完,需要很长的时间。为了提升用户体验,我们使用懒加载,当图片出现在浏览器可视区域时,才加载图片。例如各种电商页面。

网页优化

可以使用 懒加载 减少对dom的操作 精简代码,

组件之间的传值 {子组件给父组件传递数据}

先通过父组件给子组件传递方法 再通过方法,给父组件传递数据

子组件通过this.$emit()的方式将值传递给父组件

v-if和v-show 的区别

v-if

1、v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

2、v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

v-show

1、v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,

数据接口

1.接口其实就是一个url,一般对应服务器上的某个文件,对这个 url 发起请求,经过后端的一些处理后会返回一些数据(格式一般为json)

2.接口由后端提供,前端调用后端接口以获取后端数据。

key 的值唯一 (为什么)

1.vue中列表循环需加:key="唯一标识" 唯一标识尽量是item里面id等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM。

2.key主要用来做dom diff算法用的,diff算法是同级比较,比较当前标签上的key还有它当前的标签名,如果key和标签名都一样时只是做了一个移动的操作,不会重新创建元素和删除元素。

3.没有key的时候默认使用的是“就地复用”策略。如果数据项的顺序被改变,Vue不是移动Dom元素来匹配数据项的改变,而是简单复用原来位置的每个元素。如果删除第一个元素,在进行比较时发现标签一样值不一样时,就会复用之前的位置,将新值直接放到该位置,以此类推,最后多出一个就会把最后一个删除掉。

data为什么是一个函数

如果data是一个函数的话,这样每复用一次组件,就会返回一份新的data(类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据)

Object是引用数据类型,里面保存的是内存地址,单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。

MVC是什么?

答:MVC全名是Model View Controller,是模型(model)-视图-控制器(controller)的缩写,是一种软件设计模式,用一种业务逻辑,处理数据,显示分离的组织代码,将业务逻辑聚集到一个部件上,在不断和个性化定制界面与用户交互的同时,不断重新编写业务逻辑,MVC用于映射传统的输入,处理和输出功能在一个逻辑化的图形界面中。

MVVM是什么?

答:MVVM是Model,View,ViewModel的缩写,是一种设计模式。Model是数据层,View是视图层,ViewModel是一个同步View和Model的对象,View与ViewModel之间通过双向绑定建立联系,当View变化时,会自动更新到ViewModel上,反之亦然。

MVVM和MVC之间的区别是什么?

答:它实现了view和model的自动同步,也就是model的数据改变时,不再手动操作dom了,view会自动改变,MVVM中的VM并不是完全取代了C,而是抽离C中展示的业务逻辑,而不是替代C,其他视图操作业务还是放在C中实现。

浏览器

五大浏览器内核

webkit 苹果

blink 谷歌

preto 欧朋 前内核 现在 欧朋 blink现在

trident(三叉戟) IE 市场份额最大

gecko 火狐内核 跨平台性

最早浏览器 网景公司 的领航者 简称nn

发布订阅模式简介

发布订阅模式是一种消息传递模式,其中发布者发布消息,而订阅者接收和处理这些消息。它是一种松耦合的通信方式,允许发布者和订阅者在不知道彼此存在的情况下进行通信。

而订阅者可以订阅这些消息队列或主题以接收和处理消息。发布者和订阅者之间的通信是异步的,这意味着发布者发布消息后,订阅者可以在任何时候接收和处理消息。


vue传值接收

在Vue中,可以通过props属性来进行组件之间的数据传递。

首先,需要定义一个子组件(ChildComponent)并设置props属性来接收父组件传递的值。然后,在父组件中引入该子组件,并将需要传递的值作为prop传递给子组件

状态码返回值

200 - 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页

3xx - 重定向 

404 -Not Found 代表客户端错误,指的是服务器端无法找到所请求的资源

400 -请求无效,服务器不理解请求的语法

403 - 禁止访问 ,服务器拒绝请求

500 - 内部服务器错误,无法完成请求

501 - 未实现 ,服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能

Vue指令

  1. v-on
  2. v-model
  3. v-once
  4. v-show
  5. v-if、v-else、v-else-if
  6. v-for
  7. v-text和v-html
  8. v-bind

This指向

this一般会出现在函数里面,但是一般情况下只有在函数被调用执行时,才能确定this指向哪个对象。一般情况下this是指调用函数的对象。

在全局作用域下或者普通函数中this的指向一般都是window对象 

构造函数中的this,指向的是构造函数的实例,构造函数prototype对象中的函数里面的this也是实例对象

什么是Symbol

Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是JavaScript中的第七种数据类型,与undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列。

垃圾回收机制

浏览器的 Javascript 具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。其原理是:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大并且 GC 时停止响应其他操作,所以垃圾回收器会按照固定的时间间隔周期性的执行。

2. 标记清除  3. 引用计数  4. 内存管理

数组去重

  • JS数组去重的方式
    • 1.利用Set()+Array.from()
    • 2.利用两层循环+数组的splice方法
    • 3.利用数组的indexOf方法
    • 4.利用数组的includes方法
    • 5.利用数组的filter()+indexOf()
    • 6.利用Map()
    • 7.利用对象

vue的优点

  • 1、轻量级框架
  • 2、简单易学
  • 3、双向数据绑定
  • 4、组件化
  • 5、视图,数据,结构分离
  • 6、虚拟DOM
  • 7、运行速度更快
  • 数据驱动视图

数组删除【abcaaadc】删除 a 解决办法

如果只删除a 可以使用循环判断 然后,索引前移 那就在加一个 i--

如果单纯去重那就 new set

XSS攻击

XSS攻击是Web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器执行,达到攻击的目的,形成了一次有效XSS攻击

实施XSS攻击需要具备的两个条件:

2.1需要向web页面注入恶意代码;
2.2这些恶意代码能够被浏览器成功的执行。

----------------------------------------------------------------------------------------------------------

三 继承

继承写法 class继承

继承的本质就是 复制,即重写原型对象,代之以一个新类型的实例 。 核心代码是 SuperType.call (this) ,创建子类实例时调用 SuperType 构造函数,于是 SubType 的每个实例都会将SuperType中的属性复制一份, 解决了原型链继承中多实例相互影响的问题 

原型链继承

构造函数、原型和实例之间的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个原型对象的指针。

继承的本质就是复制,即重写原型对象,代之以一个新类型的实例。

优点:

  • 父类方法可以复用

缺点:

  • 父类的引用属性会被所有子类实例共享,多个实例对引用类型的操作会被篡改(代码如下);
  • 子类构建实例时不能向父类传递参数

构造函数继承

使用父类的构造函数来增强子类实例,等同于复制父类的实例给子类(不使用原型)

核心代码是SuperType.call(this),创建子类实例时调用SuperType构造函数,于是SubType的每个实例都会将SuperType中的属性复制一份,解决了原型链继承中多实例相互影响的问题。

优点:和原型链继承完全反过来

  • 父类的引用属性不会被共享
  • 子类构建实例时可以向父类传递参数

缺点:

  • 只能继承父类的
  • 实例
  • 属性和方法,不能继承原型属性/方法
  • 无法实现复用,每个子类都有父类实例函数的副本,影响性能

组合继承(上面两种结合起来)

组合上述两种方法就是组合继承。用原型链实现对原型属性和方法的继承,用借用构造函数技术来实现实例属性的继承。

优点:

  • 父类的方法可以被复用
  • 父类的引用属性不会被共享
  • 子类构建实例时可以向父类传递参数

缺点(对照注释):

  • 第一次调用
  • SuperType()
  • :给
  • SubType.prototype
  • 写入两个属性name,color。
  • 第二次调用
  • SuperType()
  • :给
  • instance1
  • 写入两个属性name,color。

实例对象inst1上的两个属性就屏蔽了其原型对象SubType.prototype的两个同名属性。所以,组合模式的缺点就是在使用子类创建实例对象时,其原型中会存在两份相同的父类实例的属性/方法。这种被覆盖的情况造成了性能上的浪费。

原型式继承(哎,就是浅拷贝)

我们举个 ,比如,现在有一个对象,叫做"中国人",还有一个对象,叫做"医生"。

请问怎样才能让"医生"去继承"中国人",也就是说,我怎样才能生成一个"中国医生"的对象?

这里要注意,这两个对象都是普通对象,不是构造函数,所以无法使用构造函数方法实现"继承"。

可以用object()方法

利用一个空对象作为中介,将某个对象直接赋值给空对象构造函数的原型。

object()本质上是对传入其中的对象执行了一次浅拷贝,将构造函数F的原型直接指向传入的对象。

优点: 父类方法可以复用

缺点:

  • 原型链继承多个实例的引用类型属性指向相同,存在篡改的可能
  • 子类构建实例时不能向父类传递参数

寄生式继承(能附加一些方法)

使用原型式继承获得一份目标对象的浅拷贝,然后增强了这个浅拷贝的能力。

优缺点其实和原型式继承一样,寄生式继承说白了就是能在拷贝来的对象上加点方法,也就是所谓增强能力。

优点:

  • 父类方法可以复用

缺点:

  • 原型链继承多个实例的引用类型属性指向相同,存在篡改的可能
  • 子类构建实例时不能向父类传递参数

寄生组合继承(最优方案)

组合继承会有两次调用父类的构造函数而造成浪费的缺点,寄生组合继承就可以解决这个问题。

核心在于inheritPrototype(subType, superType),让子类的prototype指向父类原型的拷贝,这样就不会调用父类的构造函数,进而引发内存的浪费问题。

三次握手 【的优势】tcp syn=1 第一次握手

上图主要包括三部分:建立连接、传输数据、断开连接。

建立TCP连接很简单,通过三次握手便可建立连接。

建立好连接后,开始传输数据。TCP数据传输牵涉到的概念很多:超时重传、快速重传、流量控制、拥塞控制等等。

断开连接的过程也很简单,通过四次握手完成断开连接的过程

三次握手建立连接:

第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

四次握手断开连接:

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

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

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

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

----------------------------------------------------------------------------------------------------------

四 uniapp

路由与页面跳转

uniapp的页面跳转和小程序是一样的,都是跳转配置好的页面路径, 并且tab页面也是需要使用switchTab才能实现跳转,总体上和小程序保持一致,对于熟练小程序的朋友上手没有难度,反之,当你习惯了uniapp的页面切换组件后上手小程序也很快。

 

.uniapp的配置文件、入口文件、主组件、页面管理部分

pages.json 配置文件

main.js 入口文件

App.vue 主组件

pages 页面管理部分

uniapp获取地理位置的API是什么? uni.getLocation

uniapp路由搭建 pages.json

进行路由的搭建 然后在里边也可以添加 tabBer的 下层导航

5.rpx、px、em、rem、%、vh、vw的区别是什么?

px 绝对单位,页面按精确像素展示

rem 相对单位,相对根节点html的字体大小来计算

% 一般来说就是相对于父元素

vh 视窗高度,1vh等于视窗高度的1%

vw 视窗宽度,1vw等于视窗宽度的1%

6.uniapp如何监听页面滚动

使用 onPageScroll 监听

7.如何让图片宽度不变,高度自动变化,保持原图宽高比不变?

给image标签添加 mode=‘widthFix’

8.uni-app的优缺点

a. 一套代码可以生成多端

b. 学习成本低,语法是vue的,组件是小程序的

c. 拓展能力强

d. 使用HBuilderX开发,支持vue语法

e. 突破了系统对H5条用原生能力的限制

缺点:

a. 问世时间短,很多地方不完善

b. 社区不大

c. 官方对问题的反馈不及时

d. 在Android平台上比微信小程序和iOS差

e. 文件命名受限

9.分别写出vue、uni-app中的本地存储数据和接受数据是什么?

vue:

存储:localstorage.setItem(‘key’,‘value’)

接收:localstorage.getItem(‘key’)

uni-app:

存储:uni.setStorage({key:“属性名”,data:“值”})

接收:uni.getStorage({key:“属性名”,success(e){e.data//这就是你想要取的token}})

小程序,uni-app:

1. onLoad:首次进入页面加载时触发,可以在 onLoad 的参数中获取打开当前页面路径中的参数。

2. onShow:加载完成后、后台切到前台或重新进入页面时触发

3. onReady:页面首次渲染完成时触发

4. onHide:从前台切到后台或进入其他页面触发

5. onUnload:页面卸载时触发

6. onPullDownRefresh:监听用户下拉动作

7. onReachBottom:页面上拉触底事件的处理函数

8. onShareAppMessage:用户点击右上角转发

uniApp适用于以下场景:

  • 多平台应用:如果您需要在iOS、Android和Web平台上构建应用,uniApp就是一个非常好的选择。
  • 独立APP:如果您需要构建一个独立的移动应用程序,uniApp也是一个非常不错的选择。
  • 基础应用:如果您需要构建一个基于模板的应用程序,uniApp也可以很适用。

uniapp 代码创建 打开进行点选创建

uniapp 跨域

在uniapp的 manifest.json 的源码里边进行 修改 devserver的值

"h5" : {
        "devServer" : {
            // "port":5173,
            "disableHostCheck" : true,
            "https" : false,
            "proxy" : {
                "/sys" : {
                    "target" : "https://192.168.1.160:7890",
                    "changeOrigin" : true, //是否跨域
                    "secure" : false // 设置支持https协议的代理
                }
            }
        },
        "sdkConfigs" : {
            "maps" : {}
        }
    }

前端常见面试题_echarts面试题-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值