前端面试题js+vue(2019年5月总结)

大部分来源于互联网,本人仅作了总结!!!css

js、H五、css部分

css部分

less特色:1. 变量 2. 混合(Mixins) 3. 嵌套规则 4. 运算 5. 函数 6. 命名空间 7. 做用域 8. 注释 9. 导入(Import)html

数据类型前端

1,介绍js的基本数据类型。    vue

Undefined、Null、Boolean、Number、Stringnode

2,类型判断用到哪些方法?jquery

typeofwebpack

typeof xxx获得的值有如下几种类型:undefined boolean number string object function、symbol ,比较简单,再也不一一演示了。这里须要注意的有三点:git

* typeof null结果是object ,实际这是typeof的一个bug,null是原始值,非引用类型github

* typeof [1, 2]结果是object,结果中没有array这一项,引用类型除了function其余的所有都是objectweb

* typeof Symbol() 用typeof获取symbol类型的值获得的是symbol,这是 ES6 新增的知识点

 

instanceof

用于实例和构造函数的对应。例如判断一个变量是不是数组,使用typeof没法判断,但可使用[1, 2] instanceof Array来判断。由于,[1, 2]是数组,它的构造函数就是Array。同理:

function Foo(name) {

   this.name = name

}

var foo = new Foo('bar’)

console.log(foo instanceof Foo) // true

3,JavaScript有几种类型的值?,你能画一下他们的内存图吗?

栈:原始数据类型(Undefined,Null,Boolean,Number、String)

堆:引用数据类型(对象、数组和函数)

两种类型的区别是:存储位置不一样;

(1)原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,因此放入栈中存储;

(2)引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,若是存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中得到实体

在参数传递方式上,原始类型是按值传递,引用类型是按共享传递

JS 中这种设计的缘由是:按值传递的类型,复制一份存入栈内存,这类类型通常不占用太多内存,并且按值传递保证了其访问速度。按共享传递的类型,是复制其引用,而不是整个复制其值(C 语言中的指针),保证过大的对象等不会由于不停复制内容而形成内存的浪费。

4,介绍js有哪些内置对象?    

Object 是 JavaScript 中全部对象的父对象  

数据封装类对象:Object、Array、Boolean、Number 和 String    

其余对象:Function、Arguments、Math、Date、RegEx、Error

5,如何区分数组和对象?    

一、从原型入手,Array.prototype.isPrototypeOf(obj);  利用isPrototypeOf()方法,断定Array是否是在obj的原型链中,若是是,则返回true,不然false。Array.prototype.isPrototype([]) //true

二、也能够从构造函数入手,利用对向的constructor属性

三、根据对象的class属性(类属性),跨原型链调用toString()方法。Object.prototype.toString.call(Window);

四、Array.isArray()方法。

 

6,null,undefined 的区别?

console.log(null==undefined);    //true  由于二者都默认转换成了false
console.log(typeof undefined);    //"undefined"  
console.log(typeof null);       //"object"  
console.log(null===undefined);    //false   "==="表示绝对相等,null和undefined类型是不同的,因此输出“false”

null表示没有对象,即该处不该该有值

1) 做为函数的参数,表示该函数的参数不是对象

2) 做为对象原型链的终点

undefined表示缺乏值,即此处应该有值,但没有定义

1)定义了形参,没有传实参,显示undefined

2)对象属性名不存在时,显示undefined

3)函数没有写返回值,即没有写return,拿到的是undefined

4)写了return,但没有赋值,拿到的是undefined

null和undefined转换成number数据类型

null 默认转成 0

undefined 默认转成 NaN

数组和对象有哪些原生方法,列举一下?

 数组的经常使用方法:

方法

说明

slice() 数组对象.slice(start,end)

获取数组中的某段数组元素

unshift() 数组对象.unshift(新元素1,新元素2,…,新元素n);

在数组开头添加元素

push() 数组对象.push(新元素1,新元素2,…,新元素n);

在数组末尾添加元素

shift() 数组对象.shift();

删除数组中第一个元素

pop() 数组对象.pop();

删除数组最后一个元素

toString() 数组对象.toString()

将数组转换为字符串

join() 数组对象.join("分隔符")

将数组元素链接成字符串

concat() 数组1.concat(数组2,数组3,…,数组n)

多个数组链接为字符串concat,就是“合并”的意思。

sort() 数组对象.sort(函数名)

数组元素正向排序

reverse() 数组对象.reverse();

数组元素反向排序

 

 对象的经常使用方法

obj.assign(),

字符串有哪些原生方法,列举一下?

charAt()    返回在指定位置的字符。
charCodeAt()    返回在指定的位置的字符的 Unicode 编码。
concat()    链接字符串。
indexOf()    检索字符串。
match()    找到一个或多个正则表达式的匹配。
replace()    替换与正则表达式匹配的子串。
search()    检索与正则表达式相匹配的值。
slice()    提取字符串的片段,并在新的字符串中返回被提取的部分。
split()    把字符串分割为字符串数组。
toLocaleLowerCase()    把字符串转换为小写。
toLocaleUpperCase()    把字符串转换为大写。
toLowerCase()    把字符串转换为小写。
toUpperCase()    把字符串转换为大写。
substr()    从起始索引号提取字符串中指定数目的字符。
substring()    提取字符串中两个指定的索引号之间的字符。
 

 null和undefined的区别

null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

== 和 === 的区别 

 1.===:三个等号咱们称为等同符,当等号两边的值为相同类型的时候,直接比较等号两边的值,值相同则返回true,若等号两边的值类型不一样时直接返回false。

     例:

100===“100”   //返回false
abc===“abc”   //返回false
 ‘abc’===“abc”  //返回true
NaN===NaN   //返回false
 false===false  //返回true

2.==:两个等号咱们称为等值符,当等号两边的值为相同类型时比较值是否相同,类型不一样时会发生类型的自动转换,转换为相同的类型后再做比较。
类型转换规则:

1)若是等号两边是boolean、string、number三者中任意二者进行比较时,优先转换为数字进行比较。
 2)若是等号两边出现了null或undefined,null和undefined除了和本身相等,就彼此相等
     例:

 100==“100”    //返回true
 1==true          //返回true
“1”==“01”      //返回false,此处等号两边值得类型相同,不要再转换类型了!!
 NaN==NaN  //返回false,NaN和全部值包括本身都不相等。

关于变量和常量

let

let 用来声明变量,相似于变量,可是所声明的变量,只在let命令所在的代码块内有效

须要注意的地方:

1.不存在变量提高,未声明直接报错

2.暂时性死区

3.for循环具备两个做用域,外面的变量和里面的变量互不干扰

 

const

用来声明一个只读的常量,一旦尚明,常量的值就不能够改变了,并且声明的时候必须赋值

 

须要注意的地方:

引用类型储存的是一个地址,因此用const声明的引用数据类型,只要不改变指针地址,就能够

若是为常量赋其余的值,就会报错。

数组的深拷贝

const a1 = [1,2];

1.const a2 = [...a1];

2.const [...a2] = a1;

关于本地存储和会话存储

经常使用浏览器存储方案有,cookie,session,localstorage,sessionstroage,区别在于:

1.方式: cookie经过请求头发送,在浏览器与服务器之间来回传递,sessionStroage与   localStroage不会把数据发给服务器,仅在本地保存

2.存储量​:cookie存储量小,通常在4到8kb,其他存储量大5M

3.数据有效期不一样,

     sessionStorage:仅在当前浏览器窗口关闭前有效,天然也就不可能持久保存

     localStorage:始终有效,窗口或浏览器关闭也一直保存,所以用做持久数据

     cookie只在设置的cookie过时时间以前一直有效,即便窗口或浏览器关闭。

4.做用域​

     sessionStorage不能在不一样的浏览器窗口中共享,即便是同一个页面;

     localStorage 在全部同源窗口中都是共享的

     cookie也是在全部同源窗口中都是共享的。

关于异步处理:Generator   async   promise  的区别

详细理解:https://www.jianshu.com/p/f17d577f677e

移动端适配的技术方案:

(1)经过媒体查询的方式即CSS3的meida queries

(2)以天猫首页为表明的 flex 弹性布局

(3)以淘宝首页为表明的 rem+viewport缩放 (推荐)

(4)rem 方式(推荐)

详细参考:http://www.javashuo.com/article/p-gympjfos-g.html

ES6经常使用特性

变量定义(let和const,可变与不可变,const定义对象的特殊状况)

解构赋值

模板字符串

数组新API(例:Array.from(),entries(),values(),keys())

箭头函数(rest参数,扩展运算符,::绑定this)

特色:箭头函数中的this始终指向箭头函数定义时的离this最近的一个函数,若是没有最近的函数就指向window。

1不能做为构造函数,不能使用new

2不能使用argumetns,取而代之用rest参数...解决

3不绑定this,会捕获其定义时所在的this指向做为本身的this。因为在vue中自动绑定 this 上下文到实例中,所以不能使用箭头函数来定义一个周期方法。箭头函数的this永远指向上下文的this,call、apply、bind也没法改变

4箭头函数没有原型对象

箭头函数其实只是一个匿名函数的语法糖,区别在于普通函数做用域中的this有特定的指向,通常指向window,而箭头函数中的this只有一个指向那就是指当前函数所在的对象,其实现原理其实就是相似于以前编程的时候在函数外围定义that同样,用了箭头函数就不用定义that了直接使用this

参考:https://www.jianshu.com/p/73cbeb6782a0

Set和Map数据结构(set实例成员值惟一存储key值,map实例存储键值对(key-value))

(1) Set 相似于数组,但数组能够容许元素重复,Set 不容许元素重复 


(2)Map 相似于对象,但普通对象的 key 必须是字符串或者数字,而 Map 的 key 能够是任何数据类型 


Promise对象(前端异步解决方案进化史,generator函数,async函数)

Class语法糖(super关键字)

 

总结前端性能优化的解决方案

http://www.javashuo.com/article/p-redbafbu-hv.html

优化的方向有两个:

减小页面体积,提高网络加载

优化页面渲染

 

减小页面体积,提高网络加载

静态资源的压缩合并(JS 代码压缩合并、CSS 代码压缩合并、雪碧图)

静态资源缓存(资源名称加 MD5 戳)

使用 CDN 让资源加载更快

优化页面渲染

CSS 放前面,JS 放后面

懒加载(图片懒加载、下拉加载更多)

减小DOM 查询,对 DOM 查询作缓存

减小DOM 操做,多个操做尽可能合并在一块儿执行(DocumentFragment)

事件节流

尽早执行操做(DOMContentLoaded)

使用 SSR 后端渲染,数据直接输出到 HTML 中,减小浏览器使用 JS 模板渲染页面 HTML 的时间
 

Ajax原理

(1)建立对象

var xhr = new XMLHttpRequest();

(2)打开请求

xhr.open('GET', 'example.txt', true);

(3)发送请求

xhr.send(); 发送请求到服务器

(4)接收响应

xhr.onreadystatechange =function(){}

(1)当readystate值从一个值变为另外一个值时,都会触发readystatechange事件。

(2)当readystate==4时,表示已经接收到所有响应数据。

(3)当status ==200时,表示服务器成功返回页面和数据。

(4)若是(2)和(3)内容同时知足,则能够经过xhr.responseText,得到服务器返回的内容。

浅拷贝和深拷贝

jQuery.extend第一个参数能够是布尔值,用来设置是否深度拷贝的

jQuery.extend(true, { a : { a : "a" } }, { a : { b : "b" } } );
jQuery.extend( { a : { a : "a" } }, { a : { b : "b" } } );

最简单的深拷贝

aa = JSON.parse( JSON.stringify(a) )

浅复制--->就是将一个对象的内存地址的“”编号“”复制给另外一个对象。深复制--->实现原理,先新建一个空对象,内存中新开辟一块地址,把被复制对象的全部可枚举的(注意可枚举的对象)属性方法一一复制过来,注意要用递归来复制子对象里面的全部属性和方法,直到子子.....属性为基本数据类型。总结,深复制理解两点,1,新开辟内存地址,2,递归来刨根复制。

 

事件冒泡和事件捕捉 https://blog.csdn.net/qq_40510139/article/details/89320892

闭包   https://blog.csdn.net/qq_40510139/article/details/78825156

div上下左右居中

position: absolute;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;

参考:http://www.javashuo.com/article/p-ewkqybfv-hg.html

js面试题扩展:https://www.jianshu.com/p/f1f39d5b2a2e

js设计模式:

http://www.javashuo.com/article/p-ghjzqliu-k.html

HTTP协议:

https://www.cnblogs.com/123blog/articles/10297650.html

vue部分

重中之重、Vue的双向数据绑定原理是什么?

实现数据绑定的作法有大体以下几种:

  • 发布者-订阅者模式(backbone.js)
  • 脏值检查(angular.js)
  • 数据劫持(vue.js)

答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,经过Object.defineProperty()来劫持各个属性的setter,getter,在数据变更时发布消息给订阅者,触发相应的监听回调。

这里写图片描述
具体步骤:

已经了解到vue是经过数据劫持的方式来作数据绑定的,其中最核心的方法即是经过Object.defineProperty()来实现对属性的劫持,达到监听数据变更的目的。 
要实现mvvm的双向绑定,就必需要实现如下几点: 
一、实现一个数据监听器Observer,遍历data中的属性,使用 Object.defineProperty 的get/set方法对其进行数据劫持,达到监听数据变更的目的,若有变更可拿到最新值并通知订阅者
二、实现一个指令解析器Compile,对每一个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数 
三、实现一个Watcher,做为链接Observer和Compile的桥梁,可以订阅并收到每一个属性变更的通知,执行指令绑定的相应回调函数,从而更新视图 
四、mvvm入口函数,整合以上三者

详细理解:https://www.jianshu.com/p/f194619f6f26

provide/inject的学习

https://segmentfault.com/a/1190000014095107?utm_source=tag-newest

1、什么是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 来统一管理。

2、mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操做使页面渲染性能下降,加载速度变慢,影响用户体验。
区别:vue数据驱动,经过数据来显示视图层而不是节点操做。
场景:数据操做比较多的场景,更加便捷

3、vue的优势是什么?
低耦合。视图(View)能够独立于Model变化和修改,一个ViewModel能够绑定到不一样的"View"上,当View变化的时候Model能够不变,当Model变化的时候View也能够不变。
可重用性。你能够把一些视图逻辑放在一个ViewModel里面,让不少view重用这段视图逻辑。
独立开发。开发人员能够专一于业务逻辑和数据的开发(ViewModel),设计人员能够专一于页面设计。
可测试。界面素来是比较难于测试的,而如今测试能够针对ViewModel来写。

4、 组件之间的传值?(重点)

1.父组件与子组件传值
父组件传给子组件:子组件经过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是建立一个事件中心,至关于中转站,能够用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有很多人推荐直接用VUEX,具体来讲看需求咯。技术只是手段,目的达到才是王道。)

父子组件互相调用方法

父组件中定义好了方法 hello(),在子组件中直接用:this.$parent.hello();

父组件调用子组件的方法:this.$refs.pass.fn1;

vue-router基本原理:(重点)

vue-router经过hashHistory interface两种方式实现前端路由,更新视图但不从新请求页面。

主要有两种方式:

一、hash ---- 利用URL中的hash(“#”)

二、利用History interface在 HTML5中新增的方法,

详细理解:https://www.jianshu.com/p/4295aec31302

7、vue如何实现按需加载配合webpack设置
webpack中提供了require.ensure()来实现按需加载。之前引入路由是经过import 这样的方式引入,改成const定义的方式进行引入。
不进行页面按需加载引入方式:import home from '../../common/home.vue'
进行页面按需加载的引入方式:
const home = r => require.ensure( [], () => r (require('../../common/home.vue')))

8、vuex面试相关(重点)
(1)vuex是什么?怎么使用?哪一种功能场景使用它?
vue框架中状态管理。在main.js引入store,注入。新建一个目录store,…… export 。场景有:单页应用中,组件之间的状态。音乐播放、登陆状态、加入购物车
(2)vuex有哪几种属性?

工做原理:

经过官方文档提供的流程图咱们知道,vuex的工做流程,

一、数据从state中渲染到页面;

二、在页面经过dispatch来触发action

三、action经过调用commit,来触发mutation

四、mutation来更改数据,数据变动以后会触发dep对象的notify,通知全部Watcher对象去修改对应视图(vue的双向数据绑定原理)。


(3)不用Vuex会带来什么问题?
可维护性会降低,想修改数据要维护三个地方;
可读性会降低,由于一个组件里的数据,根本就看不出来是从哪来的;
增长耦合,大量的上传派发,会让耦合性大大增长,原本Vue用Component就是为了减小耦合,如今这么用,和组件化的初衷相背。

详细理解:https://www.jianshu.com/p/1fdf9518cbdf

9、 v-show和v-if指令的共同点和不一样点
v-show指令是经过修改元素的display的CSS属性让其显示或者隐藏
v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

12、Vue中引入组件的步骤?
1)采用ES6的import … from …语法或CommonJS的require()方法引入组件
2)对组件进行注册,代码以下

十3、如何让CSS只在当前组件中起做用?

将当前组件的<style>修改成<style scoped>

十4、在Vue中使用插件的步骤
采用ES6的import … from …语法或CommonJSd的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,能够传入一个选项对象Vue.use(MyPlugin, { someOption: true })

十5、请列举出3个Vue中经常使用的生命周期钩子函数
created: 实例已经建立完成以后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, watch/event事件回调. 然而, 挂载阶段尚未开始, el属性目前还不可见mounted:el被新建立的vm. el属性目前还不可见mounted : el被新建立的 vm.el属性目前还不可见mounted:el被新建立的vm.el 替换,并挂载到实例上去以后调用该钩子。若是 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
activated: keep-alive组件激活时调用

十6、active-class是哪一个组件的属性?
vue-router模块的router-link组件。

十9、生命周期相关面试题
总共分为8个阶段:

beforeCreate(建立前) 在数据观测和初始化事件还未开始
created(建立后) 完成数据观测,属性和方法的运算,初始化事件,$el属性尚未显示出来
beforeMount(载入前) 在挂载开始以前被调用,相关的render函数首次被调用。实例已完成如下的配置:编译模板,把data里面的数据和模板生成html。注意此时尚未挂载html到页面上。
mounted(载入后) 在el 被新建立的 vm.$el 替换,并挂载到实例上去以后调用。实例已完成如下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程当中进行ajax交互。
beforeUpdate(更新前) 在数据更新以前调用,发生在虚拟DOM从新渲染和打补丁以前。能够在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在因为数据更改致使的虚拟DOM从新渲染和打补丁以后调用。调用时,组件DOM已经更新,因此能够执行依赖于DOM的操做。然而在大多数状况下,应该避免在此期间更改状态,由于这可能会致使更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁以前调用。实例仍然彻底可用。
destroyed(销毁后) 在实例销毁以后调用。调用后,全部的事件监听器会被移除,全部的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

(1)、什么是vue生命周期
答: Vue 实例从建立到销毁的过程,就是生命周期。也就是从开始建立、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,咱们称这是 Vue 的生命周期。

(2)、vue生命周期的做用是什么
答:它的生命周期中有多个事件钩子,让咱们在控制整个Vue实例的过程时更容易造成好的逻辑。

(3)、vue生命周期总共有几个阶段
答:能够总共分为8个阶段:建立前/后, 载入前/后,更新前/后,销毁前/销毁后

(4)、第一次页面加载会触发哪几个钩子
答:第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

(5)、DOM 渲染在 哪一个周期中就已经完成
答:DOM 渲染在 mounted 中就已经完成了。

(6)、简单描述每一个周期具体适合哪些场景
答:生命周期钩子的一些使用方法:
beforecreate : 能够在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted : 挂载元素,获取到DOM节点
updated : 若是对数据统一处理,在这里写上相应函数
beforeDestroy : 能够作一个确认中止事件的确认框
nextTick : 等到整个视图都渲染完毕,才会执行 vm.$nextTick 

mounted: function () {
this.$nextTick(function () {

// Code that will run only after the
// entire view has been rendered
})
}

详细原理请看:https://www.jianshu.com/p/69d447321740

二10、说出至少4种vue当中的指令和它的用法?
v-if:判断是否隐藏;v-for:数据循环;v-bind:class:绑定一个属性;v-model:实现双向绑定

二12、scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
答:css的预编译。
使用步骤:
第一步:先装css-loader、node-loader、sass-loader等加载器模块
第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss
第三步:在同一个文件,配置一个module属性
第四步:而后在组件的style标签加上lang属性 ,例如:lang=”scss”
特性:
能够用变量,例如($变量名称=值);
能够用混合器,例如()
能够嵌套

二十4、为何避免 v-if 和 v-for 用在一块儿
当 Vue 处理指令时,v-for 比 v-if 具备更高的优先级,经过v-if 移动到容器元素,不会再重复遍历列表中的每一个值。取而代之的是,咱们只检查它一次,且不会在 v-if 为否的时候运算 v-for。

vue中修改了数据但视图没法更新的状况

参考:https://blog.csdn.net/github_38771368/article/details/77155939