因为JS本身的特性带来的,如果data是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue实例的数据。如果将data作为一个函数返回一个对象,那么每一个实例的data属性都是独立的,不会相互影响了。
vuex
vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
vuex有哪几种属性?
- state :基本数据(数据源存放地)
- getters :从基本数据派生出来的数据
- mutations :提交更改数据的方法,同步!
- actions :像一个装饰器,包裹mutations,使之可以异步。
- modules :模块化Vue
vuex的原理是什么?
vuex仅仅是作为vue的一个插件而存在,不像Redux,MobX等库可以应用于所有框架,vuex只能使用在vue上,很大的程度是因为其高度依赖于vue的computed依赖检测系统以及其插件系统,vuex整体思想诞生于flux,可其的实现方式完完全全的使用了vue自身的响应式设计,依赖监听、依赖收集都属于vue 对象Property set get方法的代理劫持。
router路由
vue-router是什么?
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用(SPA)变得易如反掌。
vue-router有哪几种路由导航钩子?
- 全局钩子
- router.beforeEach 全局前置守卫 进入路由之前
- router.beforeResolve 全局解析守卫 在beforeRouteEnter调用之后调用
- router.afterEach 全局后置钩子 进入路由之后
- 单个路由独享;
- 组件级
- beforeRouteEnter 进入路由前
- beforeRouteUpdate 路由复用同一个组件时
- beforeRouteLeave 离开当前路由时
路由模式
- hash模式:使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载,其显示的网路路径中会有 “#” 号,有一点点丑。这是最安全的模式,因为他兼容所有的浏览器和服务器。
- history模式
美化后的hash模式,会去掉路径中的 “#”。依赖于Html5 的history,pushState API,所以要担心IE9以及一下的版本,感觉不用担心。并且还包括back、forward、go三个方法,对应浏览器的前进,后退,跳转操作。就是浏览器左上角的前进、后退等按钮进行的操作。 - abstract模式
适用于所有JavaScript环境,例如服务器端使用Node.js。如果没有浏览器API,路由器将自动被强制进入此模式。
路由守卫
- 全局钩子: beforeEach、 afterEach
- 独享守卫(单个路由里面的钩子): beforeEnter、 beforeLeave
- 组件内守卫:beforeRouteEnter、 beforeRouteUpdate、 beforeRouteLeave
怎么定义 vue-router 的动态路由? 怎么获取传过来的值?
在router目录下的index.js文件中,对path属性加上/:id。使用router对象的params.id。
路由的跳转方式有哪些?
- router-link标签会渲染为标签,template中的跳转都是这种;
- 另一种是编程是导航也就是通过js跳转比如router.push(/home)
vue-router怎么实现路由懒加载?
- vue异步组件技术:异步加载,vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件。
- 路由懒加载(使用import)。
- webpack提供的require.ensure(),vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。
route和router的区别
- r
o
u
t
e
r
:
V
u
e
R
o
u
t
e
r
实例,想要导航到不同
U
R
L
,使用
router:VueRouter实例,想要导航到不同URL,使用
router:VueRouter实例,想要导航到不同URL,使用router.push方法。
- $route:当前router跳转对象,里面可以获取name、path、query、params等。
axios
axios是什么?怎么使用?描述使用它实现登录功能的流程?
- 请求后台资源的模块。
- 安装:npm installaxios-S
- 然后发送的是跨域,需在配置文件中vue.config.js进行设置。js中使用import进来,
然后get或.post。返回在.then函数中如果成功,失败则是在.catch函数中
axios为什么既能在浏览器环境运行又能在服务器(node)环境运行?
因为axios在浏览器端使用XMLHttpRequest 对象发送ajax请求;在node环境使用 http 对象发送ajax请求。XMLHttpRequest 时一个API,它为客户端提供了在客户端和服务器之间传输数据的功能;process对象是一个global(全局变量),提供有关信息,控制当前的node.js进程。通过判断XMLHttpRequest和process 这两个全局变量来判断程序的运行环境,从而在不同的环境提供不同的http请求模块,实现客户端和服务端程序的兼容。
axios的特点
- Axios是一个基于 promise 的HTTP库,支持promise所有的API
- 它可以拦截请求和响应
- 它可以转换请求数据和响应数据,并对响应回来的内容自动转换成JSON类型的数据
- 安全性更高,客户端支持防御XSRF
axios相关的配置属性
- ‘url’是用于请求的服务器url
- ‘method’ 是创建请求时使用的方法,默认是get
- 'baseURL’将自动加在url前面,除非url是一个绝对URL。
- ’transformRequest‘允许在向服务器发送前,修改请求数据,只能用在’put\post\patch’这几个请求方法。
- ‘headers’是即将被发送的自定义请求头。
- ‘params’是即将与请求一起发送的url参数,必须是一个无格式对象或URLSearchParams对象
- ‘auth’表示原告i使用HTTP基础验证,并提供票据,这将设置一个Authorization头,覆写掉现有的热比一使用headers设置的自定义Authorization头
- ‘proxy’定义代理服务器的主机名称和端口
Axios 的请求拦截器和响应拦截器有什么作用?如何使用它们?
- 请求拦截器和响应拦截器是 Axios 提供的两个重要功能,用于在请求发送和响应返回时进行拦截和处理。
- 请求拦截器(Request Interceptors):在请求发送之前可以对请求进行拦截和修改,例如添加请求头、修改请求参数等。
- 响应拦截器(Response Interceptors):在收到响应数据之后可以对响应进行拦截和处理,例如统一处理错误、转换响应数据等。
webpack
webpack的作用是什么,谈谈你对它的理解?
现在的前端网页功能丰富,特别是SPA(single page web application 单页应用)技术流行后,JavaScript的复杂度增加和需要一大堆依赖包,还需要解决Scss,Less……新增样式的扩展写法的编译工作。所以现代化的前端已经完全依赖于webpack的辅助了。现在最流行的三个前端框架,可以说和webpack已经紧密相连,框架官方都推出了和自身框架依赖的webpack构建工具。
webpack的工作原理?
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。在3.0出现后,Webpack还肩负起了优化项目的责任。
webpack打包原理
- 把一切都视为模块:不管是 css、JS、Image 还是 html 都可以互相引用,通过定义entry.js,对所有依赖的文件进行跟踪,将各个模块通过 loader 和 plugins 处理,然后打包在一起。
- 按需加载:打包过程中 Webpack 通过 Code Splitting 功能将文件分为多个 chunks,还可以将重复的部分单独提取出来作为 commonChunk,从而实现按需加载。把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载
webpack的核心概念
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。告诉webpack要使用哪个模块作为构建项目的起点,默认为./src/index.js
- output :出口,告诉webpack在哪里输出它打包好的代码以及如何命名,默认为./dist
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
Webpack的基本功能有哪些?
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
- 文件优化:压缩 JavaScript、CSS、html 代码,压缩合并图片等
- 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
- 模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
- 自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
- 代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
gulp/grunt 与 webpack的区别是什么?
- 三者都是前端构建工具,grunt和gulp在早期比较流行,现在webpack相对来说比较主流,不过一些轻量化的任务还是会用gulp来处理,比如单独打包CSS文件等。grunt和gulp是基于任务和流(Task、Stream)的。
- 类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。webpack是基于入口的。
- webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。
webpack是解决什么问题而生的?
如果像以前开发时一个html文件可能会引用十几个js文件,而且顺序还不能乱,因为它们存在依赖关系,同时对于ES6+等新的语法,less, sass等CSS预处理都不能很好的解决……,此时就需要一个处理这些问题的工具。
vue的响应式原理
- 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变更双向绑定效果。
组件传参
- 父组件传给子组件
- 在子组件里定义一个props,即props:[‘msg’],msg可以是对象也可以是基本数据类型子组件传给父组件
- 这里需要使用自定义事件,在子组件中使用this.$emit(‘myEvent’) 触发,然后在父组件中使用@myEvent监听
- 兄弟组件间传值
运用自定义事件e m i t 的触发和监听能力,定义一个公共的事件总线 e v e n t B u s ,通过它作为中间桥梁,我们就可以传值给任意组件了。而且通过 e v e n t B u s 的使用,可以加深 emit的触发和监听能力,定义一个公共的事件总线eventBus,通过它作为中间桥梁,我们就可以传值给任意组件了。而且通过eventBus的使用,可以加深emit的触发和监听能力,定义一个公共的事件总线eventBus,通过它作为中间桥梁,我们就可以传值给任意组件了 - 路由间传值,i.使用问号传值
- A页面跳转B页面时使用 this.$router.push(‘/B?name=danseek’)
- B页面可以使用 this.$route.query.name 来获取A页面传过来的值
- 祖传孙
正常情况下需要借助父亲的props作为中间过渡,但是这样在父亲组件就会多了一些跟父组件业务无关的属性,耦合度高,借助$attrs可以简化些,而且祖跟孙都无需做修改 - 孙传祖
借助$listeners中间事件,孙可以方便的通知祖 - sessionStorage传值
sessionStorage 是浏览器的全局对象,存在它里面的数据会在页面关闭时清除 。运用这个特性,我们可以在所有页面共享一份数据。 - vuex
这里我也不打算介绍这个大名鼎鼎的vuex怎么用,因为要把它写清楚篇幅太长了…
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您也许不需要使用 Vuex。
Vue中key的作用
key的特殊属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。在相同父元素的子元素必须有独特的key,重复的key会导致渲染错误。
jQuery和Vue有什么不同?
jQuery专注视图层,通过操作DOM去实现页面的一些逻辑渲染;
Vue专注于数据层,通过数据的双向绑定,最终表现在DOM层面,减少了DOM操作。
Vue使用了组件化思想,使得项目子集职责清晰,提高了开发效率,方便重复利用,便于协同开发。
说出几种vue当中的指令和它的用法
- v-html:渲染文本(能解析 HTML 标签)
- v-text:渲染文本(统统解析成文本)
- v-bind:绑定数据
- v-on:绑定事件
- v-model :双向数据绑定
- v-for: 循环
- v-if v-show: 显示与隐藏
- v-once:只绑定一次
watch和computed的区别
watch是进行数据监听,然后进行相应的操作,执行方法等computed和methods的合体使用,比较耗性能,与vue性能优化相背而驰,尽量减少使用;当一条数据影响多条数据的时候就需要用watch,例子:搜索数据。
computed是数据改变进行相应的数据变化,由老数据迸发新的数据(return返回),会利用缓存机制对数据进行缓存,只有当依赖数据变化的时候才会进行相应的变化;当一个属性受多个属性影响的时候就需要用到computed,最典型的例子: 购物车商品结算的时候。
vue中的v-show和V-if是做什么用的,两者区别是什么
- v-if是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做—直到条件第一次变为真时,才会开始渲染条件块。
- v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS进行切换。
- 一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show较好;如果在运行时条件不太可能改变,则使用v-if较好。
自定义指令的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?
- 全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数。
- 组件内定义指令:directives钩子函数:bind(绑定事件触发)inserted(节点插入的时候触发)、update(组件内相关更新)
- bind 只调用一次,指令第一次绑定到元素时候调用,用这个钩子可以定义一个绑定时执行一次的初始化动作。
- inserted:被绑定的元素插入父节点的时候调用(父节点存在即可调用,不必存在document中)
- update: 被绑定与元素所在模板更新时调用,而且无论绑定值是否有变化,通过比较更新前后的绑定值,忽略不必要的模板更新
- componentUpdate :被绑定的元素所在模板完成一次更新更新周期的时候调用
- unbind: 只调用一次,指令月元素解绑的时候调用
- 钩子函数参数:el、binding
单页面应用(SPA)首屏加载慢怎么办?
- 安装动态懒加载所需插件
- 按需加载
- 使用cdn
store注入的原理?
通过全局引用mixin方法使得所有Vue实例在beforeCreate下执行init方法,这个方法将this.$store绑定vuex对象注入
keep-alive是什么?
- keep-alive 是 vue 中的内置组件,能够在组件切换过程中将状态保留在内存中,防止重复的渲染 DOM;
- keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们;
- 设置了 keep-alive 缓存的组件,会多出两个生命周期钩子(activated 和 deactivated )
监听器watch的6个用法是什么?
- 常见用法
- 绑定方法(字符串)
- deep + handler(一层层遍历,性能一般)
- immediate(马上渲染)
- 绑定多个handler
- 监听对象属性
在vue中怎么获取dom节点?
在元素上使用ref属性:ref=“domName”
用法:this.$refs.domName
vue为什么要求组件模版只能有一个根结点?
因为vue组件最终是要被各种loader打包解析的,而我们必须为loader指定一个入口。而且,模版最终是会被编译成vdom的,所以必须有一个根结点来递归遍历其子节点,渲染成一个“树”。
$nextTick是什么?作用是什么?
$nextTick是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后使用它,可以在回调中获取更新后的DOM
如何给vue定义全局方法?
- 挂载到Vue的原型上:Vue.prototype.methodsName = function(){}。
- 使用mixin:Vue.use(mixins)。
- 在mian.js中写入函数,在所有组件里可调用函数
- 写好自己需要的fun.js文件,main.js 引入并使用,在所有组件里可调用函数
用npm怎么安装、发布一个插件的?
- npm install 插件 --save:安装新插件
- npm发布插件
- npm adduser:登录,添加用户名密码邮箱(需要先在npm官网注册好账号)
- npm publish:发布插件
- npm config set registry https://registry.npm.taobao.org/:修改下载仓库为淘宝镜像(没有下载cnpm时的用法)
- npm config set registry https://registry.npmjs.org/:发布前需要修改回来
- npm unpublish[包名] --force:卸载插件
用vue怎么处理本地开发跨域问题?
- 在vue.config.js配置文件中的devServer下配置proxy本地代理
- 前端什么也不用做,后端需要开启cors,CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。
- 实际上就是在响应头添加允许跨域的源Access-Control-Allow-Origin: 字段和值(意思就是允许去哪些源地址去请求这个服务器)
vue cli项目中目录src中的文件夹分别是什么?用来做什么?
- assets:用来放置一些静态资源,如图片,字体图标等
- components:用来放置组件
- router:用来放置一些路由相关的配置
- app.vue:根组件
- main.js:入口文件
v-model的原理是什么?
v-model只是一个语法糖,其内部实现原理就是使用v-bind和input事件监听值的改变。
changeValue(e){
value = e.target.value
}
使用vue后怎么针对搜索引擎做SEO优化?
- SSR服务端渲染
- NUXT同构
- prerender-spa-plugin 预渲染
Vue模版编译原理是什么?
- Vue的编译过程就是将template转化为render函数的过程。会经历以下阶段:
生成AST树 -> 优化 -> codegen - 首先解析模版,生成AST语法树(一种用JavaScript对象的形式来描述整个模板)。 使用大量的正则表达式对模板进行解析,遇到标签、文本的时候都会执行对应的钩子进行相关处理。
- Vue的数据是响应式的,但其实模板中并不是所有的数据都是响应式的。有一些数据首次渲染后就不会再变化,对应的DOM也不会变化。那么优化过程就是深度遍历AST树,按照相关条件对树节点进行标记。这些被标记的节点(静态节点)我们就可以跳过对它们的比对,对运行时的模板起到很大的优化作用。
- 编译的最后一步是将优化后的AST树转换为可执行的代码。
sessionStorage、localStorage和cookie的区别
- 共同点:都是保存在浏览器端、且同源的
- 区别:
- cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
- 存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
- 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
- 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
- web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
- web Storage的api接口使用更方便
Vue中的过滤器如何用
vue中的过滤器可以用在两个地方:双花括号插值和 v-bind 表达式(😃,过滤器应该被添加在 JavaScript表达式的尾部,由“管道”符号指示.
使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
改变this指向call、apply与bind区别
- 前两个可以自动执行,bind不会自动执行,需要手动调用
- call、bind与apply区别:前两个都有无数个参数,apply只有两个参数,而且第二个参数为数组
vue的插槽(slot)主要分三种
- 默认插槽
- 具名插槽
- 作用域插槽
- vue中的插槽,指的是子组件中提供给父组件使用的一个占位符;
- 用标签表示,父组件可以在这个占位符中填充任何模板代码,比如HTML、组件等,填充的内容会替换掉子组件的标签(替换占位符)。
JS面试题
js数据类型
- 基本数据类型:
Number、String、Boolean、Null、Undefined、Symbol、bigInt - 引用数据类型:
object、Array、Date、Function、RegExp
map与forEach的区别
- forEach 方法,是最基本的方法,就是遍历与循环
- 默认有 3 个传参:分别是遍历的数组内容 item、数组索引 index、和当前遍历数组 Arraymap 方法
- 基本用法与 forEach 一致,但是不同的,它会返回一个新的数组,所以 callback需要有 return 值,如果没有,会返回 undefined
js变量和函数声明的提升
在js中变量和函数的声明会提升到最顶部执行,函数的提升高于变量的提升,函数内部如果用 var 声明了相同名称的外部变量,函数将不再向上寻找。匿名函数不会提升。
闭包
- 闭包就是能够读取其他函数内部变量的函数
- 闭包基本上就是一个函数内部返回一个函数
- 闭包有3个特性:
- 函数嵌套函数
- 函数内部可以引用函数外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
- 好处: 可以读取函数内部的变量;将变量始终保持在内存中;可以封装对象的私有属性和私有方法。
- 坏处: 比较耗费内存、使用不当会造成内存溢出的问题。
== 和 ===的区别
- ==是非严格意义上的相等,值相等就相等
- ===是严格意义上的相等,会比较两边的数据类型和值大小,值和引用地址都相等才相等
this
- this总是指向函数的直接调用者
- 如果有new关键字,this指向new出来的对象
- 在事件中,this指向触发这个事件的对象
map与forEach的区别
- forEach 方法,是最基本的方法,就是遍历与循环,默认有 3 个传参:分别是遍历的数组内容 item、数组索引 index、和当前遍历数组 Array
- map 方法,基本用法与 forEach 一致,但是不同的,它会返回一个新的数组,所以 callback需要有 return 值,如果没有,会返回 undefined
箭头函数与普通函数的区别?
- 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象
- 不可以当作构造函数,也就是说,不可以使用 new 命令,否则会抛出一个错误
- 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 Rest 参数代替
- 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数
防抖和节流,应用场景
- 防抖和节流都是防止某一时间频繁触发,但是原理却不一样。
- 防抖是将多次执行变为只执行一次,节流是将多次执行变为每隔一段时间执行。
- 防抖(debounce):
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
- 节流(throttle):
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
- 防抖(debounce):
继承有哪些方法
- 原型链继承
- 借用构造函数继承(伪造对象、经典继承)
- 实例继承(原型式继承)
- 组合式继承
- 寄生组合继承
- es6继承 extends
JSON字符串和JSON对象转换
- JSON字符串转换为JSON对象:
var obj = str.parseJSON();//将JSON字符串转换为JSON对象
var obj = JSON.parse(str);// 将字符串转换为JSON对象 - 将JSON对象转化为JSON字符串:
var str = JSON.stringify(obj);
var str = obj.toJSONString();
微任务和宏任务的区别
- 宏任务:当前调用栈中执行的代码成为宏任务。(主代码快,定时器等等)。
- 微任务: 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。(promise.then,proness.nextTick等等)。
- 宏任务中的事件放在callback queue中,由事件触发线程维护;微任务的事件放在微任务队列中,由js引擎线程维护。
- 微任务:process.nextTick、MutationObserver、Promise.then catch finally
- 宏任务:I/O、setTimeout、setInterval、setImmediate、requestAnimationFrame
** js 判断数据类型的几种方法**
- typeof str // “string” 字符串
- typeof num // “number” 数值
- typeof array // “object” 对象(可以和函数区别开)
- typeof date // “object” 对象
- typeof func // “function” 函数
- typeof symbol // “symbol”
同步异步
async、await:Promise的语法糖;此处使用async是为了令f()声明为异步函数,await用于等待异步结果。语法上规定await只能出现在async中。通过二者搭配,使得该函数运行完成后才可运行其它函数,即实现同步。
async f() {
var result = {}; var param = #### var url = ####
await axios.post(url, param).then(function (res) {
if (res.status == 200) {
result = res.data.data;//根据接口返回的数据进行赋值
} else {
alert("获取失败!");
}
});
},
Promise优化异步
- Promise对象用于表示一个异步操作的最终完成(或失败)及其结果的返回值
- 用Promise可以避免层层嵌套的回调函数
function A() {
return "成功111";
}
var myFirstPromise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(A()); //代码成功执行
}, 250);
});
- 由于Promise.prototype.then方法返回的是一个新的Promise对象,因此可采用链式写法,按顺序依次调用。
- 如果前一个回调函数返回的是Promise对象,这时后一个回调函数就会等待该Promise对象有了运行结果,才会进一步调用。(横向发展改为向下发展)
ES6面试题
let、const、var的区别
- 变量提升
- var 声明的变量存在变量提升,即变量可以在声明前调用,值为 undefined。
- let 和 const 不存在变量提升,变量一定要声明之后才能使用,否则会报错。
- 暂时性死区
- var 不存在暂时性死区
- let 和 const 存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
- 块级作用域
- var 不存在块级作用域
- let 和 const 存在块级作用域
- 初始值设置
- var 和 let 可以不设置初始值
- const 声明变量必须设置初始值
- 重复声明
- var 允许重复声明变量
- let 和 const 不允许重复声明变量,会抛出 SyntaxError 的错误
- 数据修改
- var 和 let 可以修改数据
- const 定义的常量是基本数据类型,不能修改。定义的常量要是引用数据类型,就可以修改。因为保存在栈内存的数据是不可以被修改的。而基本数据类型是直接存储在栈内存中的,所以不能被修改。引用数据类型在栈内存中存储的是一个指针,真正的数据存储在指针指向的堆地址,不可被修改的是指针,真正的数据是可变的。
- 重新赋值
- var 和 let 声明的变量都可以重新赋值
- const 声明的变量不能重新赋值
解构赋值
- 数组的解构赋值
const arr = ['小1','小2','小3','小泽']
let [b,q,h,ze] = arr // 或者等于 ['小1','小2','小3','小泽']
console.log(b);
console.log(q);
console.log(h);
- 对象的解构赋值
let redian = {
name: '1',
chaozuo: function () {
console.log('1');
},
dance: function () {
console.log('2');
}
}
let {chaozuo,dance} = redian;
chaozuo();
dance();
模板字符串
- ``(反引号)
- 使用回车换行:标签与标签之 间能直接换行使用
- 变量、表达式拼接:直接使用${} 进行字符串拼接
箭头函数
- 箭头函数中的this指向的是外层作用域下this的值
- 没有自己的arguments对象,但是可以访问外围函数的arguments对象
- 不能通过 new 关键字调用
- 适合使用箭头函数的场景: 与this无关的回调设置。定时器、数组方法回调。
- 不适合使用箭头函数的场景: 与this有关的回调设置。事件回调、对象中的方法。
setTimeout(() => {
//箭头函数中的this指向的是外层作用域下this的值
console.log(this.data)
},1000)
rest参数
用来代替arguments,直接获取一个真数组,方便操作 (arguments返回的是伪数组)
// rest 参数用来代替 arguments 的
function main(...args) {
console.log(arguments);
console.log(args);
}
main(1,2,3,4,5,6,7,8);
扩展运算符
…能将「数组」转为逗号分隔的「参数序列] ,是 rest 的逆运算
- 数组的展开
const arr = [1, 2, 3]
function fn () {
console.log(arguments);
}
fn(...arr); //fn(1, 2, 3)
- 对象的展开
const one = {
1: 'one'
}
const two = {
2: 'two'
}
// 进行对象的合并
const hero = {...one,...two}
console.log(hero); // {1: 'one', 2: 'two'}
最后
今天的文章可谓是积蓄了我这几年来的应聘和面试经历总结出来的经验,干货满满呀!如果你能够一直坚持看到这儿,那么首先我还是十分佩服你的毅力的。不过光是看完而不去付出行动,或者直接进入你的收藏夹里吃灰,那么我写这篇文章就没多大意义了。所以看完之后,还是多多行动起来吧!
可以非常负责地说,如果你能够坚持把我上面列举的内容都一个不拉地看完并且全部消化为自己的知识的话,那么你就至少已经达到了中级开发工程师以上的水平,进入大厂技术这块是基本没有什么问题的了。