一、var,let,cont声明变量的区别
1、var的特点
1、存在变量提升;
2、一个变量可多次声明,后面的声明会覆盖前面的声明;
3、在函数中使用var声明变量的时候,该变量是局部的;而如果在函数内不使用var,该变量是全局的。
2、let的特点
1、不存在变量提升,let声明变量前,该变量不能使用(暂时性死区);
2、let命令所在的代码块内有效,在块级作用域内有效;
3、let不允许在相同作用域中重复声明,注意是相同作用域,不同作用域有重复声明不会报错。
3、const的特点
1、const声明一个只读的变量,声明后,值就不能改变;
2、const必须初始化;
3、const并不是变量的值不能改动,而是变量指向的内存地址所保存的数据不得改动;
4、let该有的特点const都有;
4、区别
1.变量提升
var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined;
let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错。
2.块级作用域
var不存在块级作用域;
let和const存在块级作用域。
3.重复声明
var允许重复声明变量;
let和const在同一作用域不允许重复声明变量。
4.修改声明的变量
var和let可以;
const声明一个只读的常量。一旦声明,常量的值就不能改变,但对于对象和数据这种引用类型,内存地址不能修改,可以修改里面的值。
5、使用
能用const的情况下尽量使用const,大多数情况使用let,避免使用var。
const > let > var
const声明的好处,一让阅读代码的人知道该变量不可修改,二是防止在修改代码的过程中无意中修改了该变量导致报错,减少bug的产生。let声明没有产生预编译和变量提升的问题,先声明再使用可以让代码本身更加规范,let是个块级作用域,也不会污染到全局的变量声明。
最后说一点就是使用的场景说明:let一般应用于基本数据类型;const 一般应用于引用数据类型,也就是函数对象等。
二、普通函数和箭头函数的区别
声明方式不同:普通函数可以是声明式的,也可以是赋值式;而箭头函数只能是赋值式的;
this指向不同:普通函数有原型prototype,this指向不确定;箭头函数本身没有this,因为没有原型,this指向确定,指向他父级作用域;
new不同:普通函数可以new;箭头函数不能new,没有prototype属性,也不可以被当作构造函数;
传参方式:普通函数可以获取 arguments对象,箭头函数不能获取可以通过 ...rest ,用 rest 对象代替。
三、http和https的区别
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS的全称是超文本传输安全协议(Hypertext Transfer Protocol Secure),是以安全为目标的HTTP通道,是一种网络安全传输协议。在HTTP的基础上加入SSL/TLS来进行数据加密,保护交换数据不被泄露、窃取。
两者区别:
一、HTTPS协议需要到证书颁发机构CA申请证书,HTTP不用申请证书;
二、HTTP是超文本传输协议,属于应用层信息传输,HTTPS 则是具有SSL加密传安全性传输协议,对数据的传输进行加密,相当于HTTP的升级版;
三、HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
四、HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
四、es6新特性
1.新增了块级作用域(let,const)
2.提供了定义类的语法糖(class)
3.新增了一种基本数据类型(Symbol)
4.新增了变量的解构赋值
5.函数参数允许设置默认值,引入了rest参数,新增了箭头函数。
6.数组新增了一些API,如isArray / from / of 方法;数组实例新增了 entries(),keys() 和 values() 等方法。
7.对象和数组新增了扩展运算符
8.ES6新增了模块化(import / export)
9.ES6新增了Set和Map数据结构。
10.ES6原生提供Proxy构造函数,用来生成Proxy实例
11.ES6新增了生成器(Generator)和遍历器(Iterator)
五、简述vuex 模块化
在Vuex中应用的所有需要共享和被修改的数据源都存放在state对象中,State使用是单一状态树结构,当应用较为复杂,需要共享的数据较多时,state对象以及store对象都会变得很臃肿,不利于代码维护。并且大多应用都会根据业务分为不同的功能模块,很多情况下不同模块之间的数据交互并不密切,如果我们能将store也分割为不同模块,每个模块管理不同的数据,会使数据管理起来更加结构清晰,方便管理。
那么为了解决以上的问题,Vuex允许我们将store分割成模块。每个模块拥有自己的state、mutation、action、getter并且可以嵌套子模块。
六、mutation为什么不能使用异步函数
Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。
如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。
七、vue中key的作用
1. key的作用主要是为了高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使整个patch过程更加高效,减少DOM操作量,提高性能;
2. 如果不设置key,还会在列表更新时引发一些隐蔽的bug;
3. vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果
八、ts优缺点
使用TS的好处:
(1)增强代码的可读性和可维护性,强类型的系统相当于最好的文档,在编译时即可发现大部分的错误,增强编辑器的功能。
(2)包容性,js文件可以直接改成 ts 文件,不定义类型可自动推论类型,可以定义几乎一切类型,ts 编译报错时也可以生成 js 文件,兼容第三方库,即使不是用ts编写的
(3)有活跃的社区,大多数的第三方库都可提供给 ts 的类型定义文件,完全支持 es6 规范
使用 TS 的缺点:
(1)增加学习成本,需要理解接口(Interfaces)和泛型(Generics),类(class),枚举类型(Enums)
(2)短期增加开发成本,增加类型定义,但减少维护成本
(3)ts 集成到构建流程需要一定的工作量
(4)和有些库结合时不是很完美
九、vue3新特性
首先是向下兼容,Vue3 支持大多数 Vue2 的特性。甚至就拿 Vue2 的语法开发 Vue3,也是没有任何问题的。
性能的提升,每个人都希望使用的框架更快,更轻。Vue3 做到了,给开发者一个极致的体验。官方网站给出的数据是:打包大小减少 41%,初次渲染快 55%,更新快 133%,内存使用减少 54%。
新推出的Composition API ,在 Vue2 中遇到的问题就是复杂组件的代码变的非常麻烦,甚至不可维护。说白了就是封装不好,重用不畅。这个Composition API一推出,立马解决了这个问题。它是一系列 API 的合集。
其他新特性:Teleport(瞬移组件)、Suspense(解决异步加载组件问题)和全局 API 的修改和优化。
更好TypeScript支持,Vue3 的源代码就是使用TypeScript进行开发的。所以在新的版本上使用TS也更加顺畅无阻。
十、vue中路由meta的作用
vue-router路由元信息说白了就是通过meta对象中的一些属性来判断当前路由是否需要进一步处理,如果需要处理,按照自己想要的效果进行处理即可。
用法一:登录校验
用法二:通过路由元信息实现不同路由展示不同布局页面
十一、map和forEach的区别
forEach()方法不会返回执行结果,而是undefined。若数组的类型为值类型,则不会改变原数组,若想改变原数组通过index这个参数来改变;若数组的类型为引用类型,则会改变原数组。
map:若数组的类型为值类型,则会分配内存空间存储新数组并返回;若数组的类型为引用类型,则会改变原数组。
十二、Vue中watch监听第一次不触发、深度监听
第一次不触发
一:handler:其值是一个回调函数。即监听到变化时应该执行的函数。
二:deep:其值是true或false;确认是否深入监听。(一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到。)
三:immediate:其值是true或false;确认是否以当前的初始值执行handler的函数
十三、深拷贝和浅拷贝
如何区分深拷贝与浅拷贝
深拷贝和浅拷贝是针对复杂数据类型(对象及数组)来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。
深拷贝复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。 深拷贝后的对象与原来的对象是完全隔离的,互不影响,对一个对象的修改并不会影响另一个对象。
形象的来说,假设B复制了A,当修改A时,看B是否跟着变化,如果B跟着变了,那么就是浅拷贝,如果B没变,那么就是深拷贝。
深拷贝与浅拷贝的区别
在未定义显示拷贝构造函数的情况下,系统调用默认的构造函数——浅拷贝,它能够完成成员的一一复制。当数据成员没有指针时,浅拷贝是可行的;但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两个析构函数,然而导致指针悬挂现象,此时就必须要用深拷贝。
深拷贝和浅拷贝的区别在于深拷贝会在堆内存中另外申请空间来存储数据,从而解决了指针悬挂问题。
浅拷贝只进行简单的属性值的复制。
十四、宏任务和微任务
JavaScript 把异步任务又做了进一步的划分,异步任务又分为两类,分别是:
① 宏任务(macrotask)
1. 异步 Ajax 请求
2. setTimeout、setInterval、
3. 文件操作
4. 其它宏任务
② 微任务(microtask)
1. Promise.then、.catch 和 .finally
2. process.nextTick
3.其它微任务
宏任务和微任务的执行顺序
每一个宏任务执行完之后,都会检查是否存在待执行的微任务,如果有,则执行完所有微任务之后,再继续执行下一个宏任务。
十五、vue 生命周期
vue生命周期可以分为八个阶段
beforeCreate(创建前)、created(创建后)、beforeMount(载入前)、mounted(载入后)、beforeUpdate(更新前)、updated(更新后)、beforeDestroy(销毁前)、destroyed(销毁后)
十六、vue计算属性
1、什么是计算属性
写在computed对象中的属性,本质上是一个方法,不过使用时依旧当属性来使用
2.什么时候使用计算属性
一个变量的值, 需要用另外变量计算而得来
3、计算属性的配置项
get():必须要写,该函数不接受参数。当计算属性只需要get时才可以简写
get()什么时候被调用?:当初次读取计算属性或者计算属性所依赖的数据发生变化时被调用,getter函数有一个返回值,该返回值就是计算属性的值
set():可选项,接受一个可选参数(计算属性被修改之后的值)
set()什么时候被调用?: 当计算属性被修改时被调用
get()和 set()中出现的this执向vm
4、计算属性的缓存
计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果
5.计算属性整个过程
当第一次调用get()之后,Vue实例身上会出现一个与计算属性同名的属性(我称为计算属性的缓存属性),该属性的值就是调用get()返回的值
当再次调用getter之后,Vue把getter返回的值赋值给这个缓存属性
缓存属性:因此当不是初次访问计算属性时且计算属性所依赖的数据没有发生变化时,Vue实际上用的是这个属性,而不是再次执行get()
原理:底层借助了Object.defineProperty方法提供的getter和setter
十七、过滤器
1.什么是过滤器?
过滤器是对即将显示的数据做进一步的筛选处理,然后进行显示,值得注意的是过滤器并没有改变原来的数据,只是在原数据的基础上产生新的数据。
2.过滤器的使用
1、定义过滤器
全局过滤器
Vue.filter('过滤器名称',function(value1[,value2,...] ) {
//逻辑代码
})
局部过滤器
new Vue({
filters: {
'过滤器名称': function (value1[,value2,...] ) {
// 逻辑代码 }
}
})
2、过滤器使用的地方
1.双花括号插值
2.v-bind表达式
十八、MVVM的理解
MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
十九、vue组件通信的方式
组件之间通讯分为三种: 父传子、子传父、兄弟组件之间的通讯
(1)props/$emit
父传子:父组件通过import引入子组件,并注册,在子组件标签上添加要传递的属性,子组 件通过props接收,接收有两种形式一是通过数组形式[‘要接收的属性’ ],二是通过对象形式{ }
子传父:父组件向子组件传递事件方法,子组件通过$emit触发事件,回调给父组件
(2)$eimt/$on
(3)$parent / $children与 ref
二十、vue双向绑定哪个函数
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,现数据劫持是通过Object.defineProperty()来实现的。Object.defineProperty( )是用来做什么的?它可以来控制一个对象属性的一些特有操作,比如读写权、是否可以枚举