# 1.ES6新增?
*1、变量的改变*
*let:代码块内有效;不能重复声明;不存在变量提升*
*const:只读变量,声明之后不允许改变。意味着,一旦声明必须初始化,否则会报错。;*
*2、模版字符串(``)*
*3、函数*
**1、箭头函数 (sender) => { }
箭头函数最直观的三个特点。
不需要function关键字
可以省略return关键字
继承当前上下文的this关键字**
*箭头函数限制:1.不能用箭头函数进行new 操作;2.不具有this,所以不能用作构造函数*
**2、函数设置默认参数**
*4、数组新增方法*
**1、forEach():数组的遍历方法,无返回值,不改变原数组**
**2、map():map遍历数组,返回一个新数组,不改变原数组的值。**
**3、filter():filter过滤掉数组中不满足条件的值,返回一个新数组,不改变原数组的值。**
**4、reduce():reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
**
**5、some():遍历数组每一项,有一项返回true,则停止遍历,结果返回true。不改变原数组**
**6、every()://遍历数组每一项,每一项返回true,则最终结果为true。当任何一项返回false时,停止遍历,返回false。不改变原数组
// 与some()方法互补**
*5、import 和 export*
*6、Promise:就是用同步的方式去写异步代码。 仅仅是同步 的方式 代码还是异步执行,Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法 ----Promise.all()方法*
*7.解构赋值:解构赋值,简单理解就是等号的左边和右边相等。*
*8.对象新增的方法:*
**Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target**
**Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名**
*9.set和map*
**Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。**
**Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作**
#2.vue路由懒加载实现?
*当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割功能*
*1、可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):*
*2、在 Webpack 2 中,我们可以使用动态 import语法来定义代码分块点,在路由配置中什么都不需要改变,只需要像往常一样使用*
**require和import from 的区别**
*import(编译时加载)只能用于静态输入,必须在文件开始的时候,在最上层就写好,而require(运行时加载)可以实现动态加载*
#3.vue生命周期
*创建阶段:*
**1、beforeCreat:初始化了一个空的vue实例对象,对象身上只有一些默认的生命周期函数和默认事件,其他什么都没有**
**注:该阶段data和methods中的数据都还没有初始化**
**2:created:data和methods中的数据都已经初始化了,如果要操作data中的数据或者调用methods中的方法,最早只能在这个阶段**
*挂载阶段:*
**3、beforeMount:模板已经在内存中编译好了,尚未挂载到页面,此时页面还是旧的**
**4、mounted:将内存中编译的模板挂载到页面,若要操作页面上的节点,最早在该阶段**
*运行阶段:*
**1、beforeUpdate:该阶段data中的数据是最新的,但尚未和页面保持同步,页面中显示的数据还是旧的**
**2、updated:页面和data数据保持同步,页面为最新**
*销毁阶段:清除定时器*
**beforeDestroy:该阶段实例身上的data和methods、过滤器及指令都还可用**
**destroyed:组件已经被完全销毁**
#4.webpack、请配置求数据封装
*出口、入口文件、loader、*
#5.判断数组方法
*对数组和对象使用typeof,得出的结果都是"object"*
*区分数组和对象的方法:*
**使用instanceof进行判断,A instanceof B即对象A是不是构造函数B构造出来的,是数组即返回true, 不是即返回false**
**利用Object.prototype.toString.call()方法将该变量转化为代表其类型的string**
**Array.isArray(A)**
**利用constructor属性进行判断**
*数组去重*
**ES6的Array.from()**
**new Set:Set 的成员具有唯一性**
**遍历数组,建立新数组,利用indexOf判断是否存在于新数组中,不存在则push到新数组,最后返回新数组(indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置,如果要检索的字符串值没有出现,则该方法返回 -1。)**
**遍历数组,利用object对象的key值保存数组值(key不重复),判断数组值是否已经保存在object中,未保存则push到新数组并用object[arrayItem]=true的方式记录保存.**
#6.浏览器兼容问题(BOM、DOM)
#7.VUEX使用场景:
*购物车、权限登录、非父子组件传值*
#8.VUE和react对比
*相同的:*
**都使用 Virtual DOM**
**都提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件。**
**都将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库**
*不同:*
**1.优化:在 React 应用中,当某个组件的状态发生变化时,它会以该组件为根,重新渲染整个组件子树。如要避免不必要的子组件的重渲染,你需要在所有可能的地方使用 PureComponent,或是手动实现 shouldComponentUpdate 方法。同时你可能会需要使用不可变的数据结构来使得你的组件更容易被优化。
然而,使用 PureComponent 和 shouldComponentUpdate 时,需要保证该组件的整个子树的渲染输出都是由该组件的 props 所决定的。如果不符合这个情况,那么此类优化就会导致难以察觉的渲染结果不一致。这使得 React 中的组件优化伴随着相当的心智负担。
在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染。你可以理解为每一个组件都已经自动获得了 shouldComponentUpdate,并且没有上述的子树问题限制。
Vue 的这个特点使得开发者不再需要考虑此类优化,从而能够更好地专注于应用本身。**
**2.语法:在 React 中,一切都是 JavaScript,所有的组件的渲染功能都依靠 JSX,vue则是模板**
**3.规模:Vue 的路由库和状态管理库都是由官方维护支持且与核心库同步更新的。React 则是选择把这些问题交给社区维护,因此创建了一个更分散的生态系统。但相对的,React 的生态系统相比 Vue 更加繁荣。**
**4.原生渲染:React Native 能使你用相同的组件模型编写有本地渲染能力的 APP (iOS 和 Android)。能同时跨多平台开发,对开发者是非常棒的。相应地,Vue 和 Weex 会进行官方合作**
#9.继承方式
*1、属性拷贝:就是将对象的成员遍历复制一份给需要继承的对象*
*2、原型式继承:借用构造函数的原型对象实现继承*
*3、原型链继承:即 子构造函数.prototype = new 父构造函数()*
*4、借用构造函数:使用call和apply借用其他构造函数的成员, 可以解决给父构造函数传递参数的问题, 但是获取不到父构造函数原型上的成员.也不存在共享问题*
*5、组合继承:借用构造函数 + 原型式继承*
#10.vue双向绑定原理
*通过数据劫持以及结合发布者-订阅者来实现的,数据劫持是利用ES5的Object.defineProperty(obj, key, val)来劫持各个属性的的setter以及getter,在数据变动时发布消息给订阅者,从而触发相应的回调来更新视图。*
```6217 9979 0000 2343 648```
**1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者**
**2.实现一个订阅者Watcher,作为连接Observer和Compile的桥梁,可以收到属性的变化通知并执行相应的函数,从而更新视图。**
**3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。**
#11.原型链:js中每个对象都有一个_proto_属性指向这个对象构造函数的prototype对象,这个prototype对象也有一个_proto_属性,他们的根是null
#作用域与作用域链:作用域就是代码的执行环境,全局执行环境就是全局作用域,函数的执行环境就是私有作用域,它们都是栈内存#
*私有作用域 ----> 函数执行都会形成一个私有作用域
全局作用域 ----> 页面一打开就会形成一个全局的作用域*
*在 Web 浏览器中,全局执行环境被认为是 window 对象,全局执行环境直到应用程序退出时,如关闭浏览器或网页,才会被销毁*
*作用域链:当在内部函数中,需要访问一个变量的时候,首先会访问函数本身的变量对象,是否有这个变量,如果没有,那么会继续沿作用域链往上查找,直到全局作用域。如果在某个变量对象中找到则使用该变量对象中的变量值*
#13、深拷贝与浅拷贝:
*ECMAScript变量包含两种不同数据类型的值:基本数据类型和引用数据类型。
基本数据类型:名值存储在栈内存中;
引用数据类型:名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值。
目前基本数据类型有:Boolean、Null、Undefined、Number、String、Symbol,引用数据类型有:Object、Array、Function、RegExp、Date等
深拷贝与浅拷贝的概念只存在于引用数据类型*
*浅拷贝方法:*
**1、Object.assign(target, source)**
**2.扩展运算符:语法:var cloneObj = { ...obj };**
**3.Array.prototype.slice() slice(start,end) 方法可从已有的数组中返回选定的元素()**
*深拷贝方法:*
**2、JSON.parse(JSON.stringfy()) 缺点:不可以拷贝 undefined , function等类型**
**3、递归去复制所有层级属性**
``` var obj1 = {
a:{
b:1
}
};
function deepClone(obj) {
var cloneObj = {}; //在堆内存中新建一个对象
for(var key in obj){ //遍历参数的键
if(typeof obj[key] ==='object'){
cloneObj[key] = deepClone(obj[key]) //值是对象就再次调用函数
}else{
cloneObj[key] = obj[key] //基本类型直接复制值
}
}
return cloneObj
}
var obj2 = deepClone(obj1);
obj1.a.b = 2;
console.log(obj2); //{a:{b:1}}```
**4、slice方法**
**5、concat**
#14、F5刷新与在地址栏按回车的区别:
*“F5刷新”,它是在你现有页面的基础上,检查网页是否有更新的内容。在检查时,会保留之前的一些变量的值;
“转到”和在地址栏回车,则相当于你重新输入网页的URL访问,这种情况下,浏览器会尽量使用已经存在于本机中的缓存。
也就是说,“F5刷新” 是取网页的新内容来更新本机缓存,在更新的同时保留之前的一些变 量;“转到”则是一种全新的访问,它会尽量使用本机缓存中的文件,但不会保留之前的变量*
#15、vue 文件压缩的方式:
*1、vue-router懒加载: 懒加载的意思是当路由被访问的时候才加载对应组件,而不是在首页就全部加载*
*2、工程文件打包的时候不生成.map文件:map文件的作用是帮助编译后的代码调试,但是我们上线的代码已经调试完成,所以上线时可以不生成.map文件,在config/index.js中将productionSourceMap的值修改为false,就可以在编译时不生成.map文件了*
*3、gzip压缩*
*4、使用的是nginx服务器,找到nginx.conf文件目录,在配置文件中配置支持gzip压缩*
*5、CDN*
*6、VUE异步组件(require.ensure()(webpack异步加载|代码分割)):异步加载组件,减轻首页负担*
*7、服务器端渲染*
*8、预渲染*
#16、性能优化:
*1、HTTP 优化:
减少请求次数
减少单次请求所花费的时间*
*2、浏览器缓存策略*
*3、CDN*
*4、图片优化*
*5、服务端渲染*
*6、css优化:
CSS 是阻塞的资源。浏览器在构建 CSSOM 的过程中,不会渲染任 何已处理的内容。即便 DOM 已经解析完毕了,只要 CSSOM 不 OK,那么渲染这个事情就不 OK。我们将 CSS 放在 head 标签里 和尽快 启用 CDN 实现静态资源加载速度的优化
避免使用通配符,只对需要用到的元素进行选择。
关注可以通过继承实现的属性,避免重复匹配重复定义。
少用标签选择器、
减少嵌套*
*7、js放在底部*
*8、减少回流和重绘*
*9、节流与防抖:所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间*
**防抖函数:**
``` * @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
function debounce(func,wait,immediate) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}```
*节流(throttle)
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率*
```* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 表时间戳版,2 表定时器版
*/
function throttle(func, wait ,type) {
if(type===1){
let previous = 0;
}else if(type===2){
let timeout;
}
return function() {
let context = this;
let args = arguments;
if(type===1){
let now = Date.now();
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}else if(type===2){
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
}```
##JavaScript闭包了解么
*闭包即为函数,但是我们通常所说的闭包是指有权访问并操作别的函数作用域中变量的函数。一般表现形式为函数中返回函数。通常我们开发中就会有很多的闭包比如定时器、事件监听、IIFE等。此题是一个借题发挥涨分的题目,我们可以谈谈闭包的高级用法,比如单例模式中的使用、js的节流和防抖甚至可以谈一谈js的运行机制,gc机制*
#17、盒子居中:translate、flex、上下左右为0、display: table-cell
#18、跨域:
*1、JSONP:动态添加一个