前端面试总结

一:ES6
对es6 了解
新增模板字符串(为JavaScript 提供了简单的字符串插值功能)、
箭头函数( 操作符左边为输入的参数, 而右边则是进行的操作以及返回的
值Inputs=>outputs 。)、
for-of (用来遍历数据—例如数组中的值。)
arguments 对象可被不定参数和默认参数完美代替。
ES6 将promise 对象纳入规范,提供了原生的Promise 对象。
增加了let 和const 命令,用来声明变量。增加了块级作用域。let 命令实际上就增加了块级
作用域。
ES6 规定, var 命令和function 命令声明的全局变量,属于全局对象的属性;
let 命令、const 命令、class 命令声明的全局变量,不属于全局对象的属性。
还有就是引入module 模块的概念
ES5 与ES6 区别

  1. 系统库的引用
    ES5 中的引用需要先使用require 导入React 包,成为对象,再去进行真正引用
    ES6 里,可以使用import 方法来直接实现系统库引用,不需要额外制作一个类库对象
  2. 导出及引用单个类
    ES5 中,要导出一个类给别的模块使用,一般通过module.exports 来实现,引用时,依然通过require
    方法来获取。
    ES6 中,使用export default 实现同样的功能,但要使用import 方法来实现导入。
    ES5 和ES6 的导入导出方法是成对出现的,不可以混用。
  3. 定义组件
    ES5 中,组件类的定义通过React.createClass 实现。
    注意:ES5 中React.createClass 后面是需要小括号的,且结尾必须有分号。
    在ES6 里,让组件类去继承React.Component 类就可以了。
    注意:这里结尾时不会出现小括号,也不需要添加分号。
    解构赋值
    解构赋值:
    其实就是分解出一个对象的解构,分成两个步骤:
  4. 变量的声明
  5. 变量的赋值
    原理:
    ES6 变量的解构赋值本质上是“模式匹配”,只要等号两边的模式相同,左边的变
    量就会被赋予匹配右边的值,
    如果匹配不成功变量的值就等于undefined
    只要某种数据结构具有Iterator 接口,都可以采用数组形式的解构赋值。
    如果不使用默认值,则不会执行默认值的函数
    解构成对象,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined 和
    null 无法转为对象,所以对它们进行解构赋值,都会报错。
    解构成数组,等号右边必须为可迭代对象
  6. 数组的解构赋值
    let [a, b, c] = [1, 2, 3];
    let [x, [y, [z, q], w]] = [1, [2, [3], 4]];
  7. 对象的解构赋值
    let {
    a = 1,
    b = 2,
    c
    } = {
    a: 3,
    c: 4
    };
  8. 字符串的解构赋值
    var [x, y, z] = fn({
    c: 33,
    a: 22,
    b: 55
    });
    模板字符串
    模板字符串是增强版的字符串,用反引号(`)标识,可以当作普通字符串使用,也可以用来
    定义多行字符串
    for…of 与for…in 的区别
    1.for in 可以遍历对象,for of 不能遍历对象
    2.for of 可以用来遍历map 集合,for in 不能遍历map 集合
    3.for in 遍历数组得到的是数组的下标,for of 遍历数组得到的是数组的元素
    4.for in 遍历键for of 遍历值
    for each、for in、for of 的区别
  • foreach用于遍历数组,是数组的一个方法。不支持return。
  • for ... in获取的对象是index 索引值。
  • for ... of获取的是对象里的值。
    遍历出对象中的key 值
    for…in… rnn7 妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹
    妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹妹
    for…in…是遍历对象的所有key 值。
    Object.keys()
    Object.keys() 方法会返回一个key 值的数组。
    Set map keys es6 map
    Set 1:ES6 提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
    2:Set 函数可以接受一个数组(或者具有iterable 接口的其他数据结构)作为参数,用来初
    始化。3:向Set 加入值的时候,不会发生类型转换,
    4:Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。
    下面先介绍四个操作方法。
    add(value):添加某个值,返回Set 结构本身。
    delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
    has(value):返回一个布尔值,表示该值是否为Set 的成员。
    clear():清除所有成员,没有返回值。
    5:Array.from 方法可以将Set 结构转为数组。
    Map: 1:JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用
    字符串当作键。
    2:set(key, value)
    set 方法设置键名key 对应的键值为value,然后返回整个Map 结构。如果key 已经有值,
    则键值会被更新,否则就新生成该键。
    3:get(key)
    get 方法读取key 对应的键值,如果找不到key,返回undefined
    4:has(key)
    has 方法返回一个布尔值,表示某个键是否在当前Map 对象之中。
    5:delete(key)
    delete 方法删除某个键,返回true。如果删除失败,返回false。
    6:clear()
    clear 方法清除所有成员,没有返回值。
    7:Map 转为数组:拓展运算符
    8:数组转为Map
    将数组传入Map 构造函数,就可以转为Map。
    9:Map 转为对象
    如果所有Map 的键都是字符串,它可以无损地转为对象。
    箭头函数与普通函数的区别?
    箭头函数箭头函数不绑定this,会捕获其所在的上下文的this 值,作为自己的this 值。
    箭头函数不可以当作构造函数,也就是说,不可以使用new 命令,否则会抛出一个错误。
    箭头函数不可以使用arguments 对象,该对象在函数体内不存在。如果要用,可以用Rest 参数代
    替。
    不可以使用yield 命令,因此箭头函数不能用作Generator 函数。
    箭头函数没有原型属性
    箭头函数通过call() 或apply() 方法调用一个函数时,只传入了一个参数,对this 并没有影
    响。
    使用箭头函数优点是什么
    作用域安全:在箭头函数之前,每一个新创建的函数都有定义自身的this 值(在构造函数中是新对象;
    在严格模式下,函数调用中的this 是未定义的;如果函数被称为“对象方法”,
    则为基础对象等),但箭头函数不会,它会使用封闭执行上下文的this 值。
    简单:箭头函数易于阅读和书写
    清晰:当一切都是一个箭头函数,任何常规函数都可以立即用于定义作用域。开发者总是可以查找
    next-higher 函数语句,以查看this 的值
    拓展运算符…
    可以将数组或对象里面的值展开;还可以将多个值收集为一个变量
    Symbol
    Symbol 是一种基本类型。Symbol 通过调用symbol 函数产生,它接收一个可选的名字参数,该
    函数返回的symbol 是唯一的
    原始数据类型:不是对象,不能使用new 命令创建,不能添加属性;
    表示独一无二的值:
    symbol 值作为属性名时,该属性是公开属性,非私有;
    symbol 作为属性时,不可被遍历;
    call() 、apply()和bind() 的区别和作用?
    相同第一个参数都是改变this 上下文指向
    不同就在于第二个参数,apply 传入数组
    bind 改变运行时上下文
    bind,apply 运行时调用call 及时调用
    class
    1、需要new,否则无法调用类构造函数
    2、类方法是不可枚举的。对于原型中的所有方法,类定义将enumerable(可枚举性)标志设置
    为false。
    3、类总是使用严格模式的。这意味着类构造中的所有代码都自动处于严格模式。
    4、class 语法相对原型、构造函数、继承更接近传统语法,它的写法能够让对象原型的写法更加
    清晰、面向对象编程的语法更加通俗
    var、let、const
    var 定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
    let : 用于取代var 声明变量
    let 不做变量提升,只能先声明,后使用
    在同一个作用域中不能重复声明一个变量。
    let 声明的全局变量不再是window 对象的属性
    let 声明会产生块级作用域
    声明的变量只在块级作用域内有效;
    const : 声明常量
    使用时必须初始化,
    只能一次性声明,如果声明的是值类型,下面不能修改。
    为了区分变量构造函数,用全大写书写
    or
    var 声明的变量会挂载在window 上,而let 和const 声明的变量不会
    var 声明变量存在变量提升,let 和const 不存在变量提升
    let 和const 声明形成块作用域
    同一作用域下let 和const 不能声明同名变量
    const
    一旦声明必须赋值,不能使用null 占位。
    声明后不能再修改
    如果声明的是复合类型数据,可以修改其属性
    暂时性死区和堆锁定
    变量提升:如果变量声明在函数里面,则将变量声明提升到函数的开头
    如果变量声明是一个全局变量,则将变量声明提升到全局作用域的开头
    暂时性死区:在代码块内,使用let 命令声明变量之前,该变量都是不可用,
    暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在
    了,但是不可获取,
    只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
    堆区、栈区
    栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。
    堆区(heap)— 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS 回收。
    堆(数据结构):堆可以被看成是一棵树,如:堆排序;
    栈(数据结构):一种先进后出的数据结构。
    深拷贝浅拷贝
    浅拷贝的意思就是只复制引用(指针),而未复制真正的值
    const originArray = [1,2,3,4,5];
    const cloneArray = originArray;
    cloneArray.push(6);
    console.log(cloneArray);
    console.log(originArray);
    深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。
    var array = [
    { number: 1 },
    { number: 2 },
    { number: 3 }
    ];
    function copy (obj) {
    var newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== ‘object’){
    return;
    } for(var i
    in obj){
    newobj[i] = typeof obj[i] === ‘object’ ?
    copy(obj[i]) : obj[i];
    }
    return newobj
    }
    var copyArray = copy(array)
    实现深拷贝的方法:利用JSON 对象中的parse 和stringify
    利用递归来实现每一层都重新创建对象并赋值
    赋值运算符= 实现的是浅拷贝,只拷贝对象的引用值;
    JavaScript 中数组(concat 和slice >和对象( Object.assgn 和…拓展运算符)
    自带的拷贝方法都是“首层浅拷贝”:第一层进行深拷贝,然后后面的是浅拷贝
    JSON.stringify 实现的是深拷贝,但是对目标对象有要求
    (非undefined,function,symbol 会在转换过程中被忽略);
    若想真正意义上的深拷贝:递归。
    递归深层应用
    阶乘,深拷贝
    promise
    构造函数,是ES6 中提出的异步编程解决方案,同步操作的异步代码,可以用来解决回调地狱
    首先promise 是一个对象如果使用的时候需要new Promise 参数是一个一个回调函数回调函数中
    有2 个参数resolve(成功) reject(失败) 在异步操作的内部进行调用同时也可以进行传值,但是传值
    只能传递一个值,如果通知成功或者失败以后可以通过then 去执行下一步操作.then 的参数是2 个回
    调函数,第一个回调函数是成功的回调第二个回调是失败的回调失败的回调也可以catch()构造一
    个Promise ,最基本的用法如下:
    var promise = new Promise(function(resolve, reject) {
    if (…) { // succeed
    resolve(result);
    } else { // fails
    reject(Error(errMessage));
    }
    });
    jQuery 的ajax 返回的是promise 对象吗?
    不是,jquery 的ajax 返回的是deferred(延迟)对象,通过promise 的resolve()方法将其转
    换为promise 对象。
    promise 只有2 个状态,成功和失败,怎么让一个函数无论成功还是失败都能被调用?
    使用promise.all(),Promise.all 方法用于将多个Promise 实例,包装成一个新的Promise 实例。
    处理一个以promise 实例为元素的数组:
    promise.all() promise.race()
    promise 链式调用
    Promise.prototype.then() ,Promise 实例具有then 方法,也就是说,then 方法是定义在原型对象
    Promise.prototype 上的。它的作用是为Promise 实例添加状态改变时的回调函数。前面说过,then
    方法的第一个参数是resolved 状态的回调函数,第二个参数(可选)是rejected 状态的回调函数。
    then 方法返回的是一个新的Promise 实例(注意,不是原来那个Promise 实例)。因此可以采用链式
    写法,即then 方法后面再调用另一个then 方法。
    getJSON("/posts.json").then(function(json) {
    return json.post;
    }).then(function(post) {
    // …
    });
    第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。
    采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返
    回的还是一个Promise 对象(即有异步操作),这时后一个回调函数,就会等待该Promise 对象的状
    态发生变化,才会被调用。
    promise 应用:
    ajax 封装:将ajax 的数据请求和数据处理分别放在不同的模块中进行管理,降低后期维护成
    本,便于管理。
    1:首先,将所有的url 放在一个模块中统一处理。
    2:第二步,将所有的数据请求这个动作放在同一个模块中统一管理。
    3:第三步:就是拿到数据并且处理数据了。
    图片加载的问题
    有一些图片需要放置在某一个块中,比如头像,比如某些图片列表。可是源图片的尺
    寸可能很难保证长宽比例都是一致的,
    如果我们直接给图片设定宽高,就有可能导致图片变形。变形之后高大上的页面就直
    接垮掉了。
    因此为了解决这个问题,我们需要一个定制的image 组件来解决这个问题。我们期望
    图片能够根据自己的宽高比,合理的缩放,
    保证在这个块中不变形的情况下尽可能的显示更多的内容。获取图片的原始宽高,需
    要等到图片加载完毕之后才能获取。
    此时就需要调用promise 对象
    自定义弹窗的处理
    利用Promise,当我们点击确认时,状态变成resolved,点击取消时,状态变成rejected。
    这样也方便将弹窗生成与后续的操作处理区分开来。
    promise 和setTimeout 执行顺序
    Promise 比setTimeout()先执行。
    因为Promise 定义之后便会立即执行,其后的.then()是异步里面的微任务。而setTimeout()是异步的宏
    任务。宏任务的优先级高于微任务,每一个宏任务执行完毕都必须将当前的微任务队列清空
    setTimeout、Promise、Async/Await 的区别
    ES7 的async/await 提案,async/await 是一个用同步思维解决异步问题的方案
    async 结果是一个promis 对象,await 必须在async 中执行,await 关键字后面跟Promise 对象**
    强制后面点代码等待直到Promise 对象resolve**,主要替传统的callback 嵌套
    async 用于声明一个函数是异步的
    await 用于等待异步完成
    await 只能在async 函数中使用
    async 返回一个promise
    await 后边永远跟的是一个promise,如果是一个非promise,则会自动转换为promise
    Async、Await 是通过Generator + Promise 实现
    二:跨域相关
    Ajax
    概念:
    Ajax 是一种在无需重新加载整个网页(刷新页面)的情况下,能够更新部分网页的技术。
    优势:
    无刷新更新数据;异步与服务器通信;前端和后端负载平衡;
    原理:
    首先创建一个XMLHttpRequest 对象,通过这个对象的open 方法与服务器建立连接,并通过该
    对象的send 方法将请求发送给服务器,最后通过onreadystatechange 监听连接的整个过程,当前服
    务器成功响应数据时,通过回调函数返回给客户端。
    优点:
  1. 通过异步模式,提升了用户体验。来自服务器的新内容可以动态更改,无需重新加载整个
    页面。
  2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用
  3. Ajax 在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器
    负载。
    缺点:
    1.ajax 不支持浏览器back 按钮。
    2.安全问题AJAX 暴露了与服务器交互的细节。
    3.对搜索引擎的支持比较弱。
    4.破坏了程序的异常机制。
    Ajax,axios,fetch 区别: ajax axios
    ajax 是一种在无需重新加载整个网页(刷新页面)的情况下,能够更新部分网页的技术。是一
    个技术方案/开发标准,对于jquery 来说是一个方法
  • fetch,是规范,是标准,是宿主的一个方法
  • axios 是基于Promise 的、用于浏览器和node.js 的HTTP 客户端;是一个库,提供了一些
    并发请求的接口
    axios 是一种对ajax 的封装,fetch 是一种浏览器原生实现的请求方式,跟ajax 对等
    ajax 是最早出现发送后端请求的技术,属于原生js 范畴,核心是使用XMLHttpRequest 对象,使用
    较多并有先后顺序的话,容易产生回调地狱。
    fetch 号称可以代替ajax 的技术,是基于es6 中的Promise 对象设计的,参数和jQuery 中的ajax
    类似,它并不是对ajax 进一步封装,它属于原生js 范畴。没有使用XMLHttpRequest 对象。
    axios 不是原生js,使用时需要对其进行安装,客户端和服务器端都可以使用,可以在请求和相
    应阶段进行拦截,基于promise 对象。
    Ajax
    对原生XHR 封装,增添了对JSONP 的支持
    针对MVC 的编程,不符合MVVM
    基于原生的XHR 开发,已有fetch 的替代方案
    Jquery 整个项目太大,单纯使用ajax 要引入整个Jquery 非常不合理,若个性化打包,则有不
    能享受CDN 服务
    Axios
    从node.js 创建http 请求
    支持Promise API
    客户端支持防止CSRF : 让每个请求都带一个从cookie 拿到的key, 根据浏览器同源策略,假
    冒的网站拿不到key.
    提供了一些并发接口
    体积比较小
    Fetch
    符合关注分离,没有将输入,输出和用事件来跟踪的状态混在在一个对象里
    更加底层,提供的API 丰富
    脱离了XHR,ES 最新的实现方式
    跨域处理,(同源策略,浏览器的请求除非设置跨芋头或借助JSONP,不然不能跨域)
    fetch 需要填的坑:
    只对网络请求报错,对于400,500 都当做成功请求
    默认不带cookie,需要配置
    不支持abort,不支持超时控制。使用setTimeout 及Promise.reject 的实现的超时控制并不能阻
    止请求过程继续在后台运行,造成了流量的浪费
    fetch 不能原生监测请求的进度,而XHR 可以
    如果解决ajax 无法后退的问题?
    html5 里引入了新的API,即:history.pushState,history.replaceState
    可以通过pushState 和replaceSate 接口浏览器历史,并且改变当前页面的URL
    onpopstate 监听后退
    jsonp、跨域(反向代理)
    jsonp 原理:
    利用src 的跨域属性,动态创建script 标签,给src 指定跨域的接口,去访问对方的资源,由指定
    的回调函数将资源返回(jsonp 只能发送get 请求)。
    跨域方式
    jsonp
    主要利用浏览器对script 资源请求没有同源限制
    前端使用script 发送请求携带回调的参数名,接收了个函数回调
    跨域资源共享(cors)iE 支持10 以上
    porxy 代理
    websocks
    axios
    服务端代理(反向代理)
    避开浏览器同源策略
    允许所有形式请求*头
    正向代理反向代理
    正向代理是代理客户端,为客户端收发请求,使真实客户端对服务器不可见;主要是用来解决访
    问限制问题
    反向代理是代理服务器端,为服务器收发请求,使真实服务器对客户端不可见。提供负载均衡、
    安全防护等作用
    正向代理的用途:
    1.访问原来无法访问的资源,如google
    2.可以做缓存,加速访问资源
    3.对客户端访问授权,上网进行认证
    4.代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
    反向代理的作用:
    1.保证内网的安全,阻止web 攻击,大型网站,通常将反向代理作为公网访问地址,Web 服务
    器是内网
    2.负载均衡,通过反向代理服务器来优化网站的负载
    同步、异步
    同步是阻塞模式,异步是非阻塞模式。
    同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进
    程将会一直等待下去,直到收到返回信息才继续执行下去;
    异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返
    回时系统会通知进程进行处理,这样可以提高执行的效率。
    举例:同步:alert;异步:setTimeout
    异步应用:
    定时任务:setTimeout(定时炸弹)、setInterval(循环执行);
    网络请求:ajax 请求、动态加载
    事件绑定
    ES6 中的Promise
    异步加载和延迟加载
    1.异步加载的方案: 动态插入script 标签
    2.通过ajax 去获取js 代码,然后通过eval 执行
    3.script 标签上添加defer 或者async 属性
    4.创建并插入iframe,让它异步执行js
    5.延迟加载:有些js 代码并不是页面初始化的时候就立刻需要的,而稍后的某些情况才需
    要的
    任务队列和Event Loop(事件循环)
    Iterator 遍历器
    遍历器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要
    部署Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)
    Iterator 的作用:
    1:是为各种数据结构,提供一个统一的、简便的访问接口;
    2:是使得数据结构的成员能够按某种次序排列;
    3:是ES6 创造了一种新的遍历命令for…of 循环,Iterator 接口主要供for…of 消费。
    默认部署了Iterator 的数据有Array、Map、Set、String、TypedArray、arguments、NodeList 对
    象,ES6 中有的是Set、Map、
    三:http
    http 特点:
    简单快捷,灵活,无连接(连接一次即断开),无状态(第二次请求时,服务器不记录之前状态)
    HTTP 报文的组成部分
    请求报文,响应报文
    请求报文包含:请求行,请求头,空行,请求体
    响应报文包含:状态行,向应头,空行,响应体
    http 方法:
    GET:获取资源,POST:传输资源,put:更新资源,DELETE:删除资源,HEAD:获得报文首部
    get poost 区别:

get: url 地址后传参(请求头) 传递数据小1K 传递速度快不安全
post: http 请求体中传参传递数据大2M 传递速度慢相对安全
浏览器回退时,get 不会重新请求,post 会;get 会被浏览器主动缓存,post 不会
持久链接/http 长连接:
轮询:http1.0 中,客户端每隔很短的时间,都会对服务器发出请求,查看是否有新的消息,性
能浪费
长连接:HTTP1.1 中,通过使用Connection:keep-alive 进行长连接,客户端只请求一次,服务器
持续保持连接
长连接中的管线化:
管线化就是,将请求打包,一次性发过去,一次响应回来
长连接时,默认的请求: 请求1 --> 响应1 -->请求2 --> 响应2 --> 请求3 --> 响应3
长连接中的管线化,请求:请求1 --> 请求2 --> 请求3 --> 响应1 --> 响应2 --> 响应3
http 状态码
200(请求成功)
202(已经接收未处理)
300(请求被重定向)
表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。
304 读取缓存
请求的资源未更新
302 临时重定向
4 开头(请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
401
未授权
403
被拒绝
404
没找到页面
5 开头(服务器错误) 这些错误可能是服务器本身的错误,不是请求出错。
500:服务器内部错误
501:服务器无法识别
503:服务出错
http 与https 区别
http 是超文本传输协议,信息是明文传输
http 协议是运行在TCP 之上。传输内容都是明文,客户端和服务器端都无法验证对方的身份。
HTTPS 协议是由SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议
http 和https 使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443
http 效率更高,https 安全性更高
https 中的s 代表
HTTP 协议中的内容都是明文传输,HTTPS 的目的是将这些内容加密,确保信息传输安全。最后
一个字母S 指的是SSL/TLS 协议,它位于HTTP 协议与TCP/IP 协议中间。
同源策略:
同协议,同域名,同端口
限制:Cookie、LocalStorage 和IndexDB 无法获取;无法获取和操作DOM;不能发送Ajax 请

如何实现浏览器内多个标签页之间的通信?
调用localstorge、cookies 等本地存储方式
跨域通信的几种方式
JSONP、WebSocket、CORS(跨域时,浏览器会拦截Ajax 请求,并在http 头中加Origin)、
Hash(Hash 的改变,页面不会刷新)、postMessage
存储
cookie
cookie 在浏览器请求中每次都会附加请求头中发送给服务器
4kb 左右
兼容性好
localStorage(持久存储)
localStorage 保存数据会一直保存没有过期时间,不会随浏览器发送给服务器。大小5M,兼容
IE8
sessionStorage(临时会话)
仅当前页面有效一旦关闭就会被释放。也不会随浏览器发送给服务器。大小5M 兼容到IE8
session
session 数据放在服务器上
将登陆信息等重要信息存放为SESSION
session 不宜挂过多数据,访问人数多会占用性能
cookie 明码,不是很安全
如何删除一个cookie
1.将时间设为当前时间往前一点。
2.expires 的设置
document.cookie = ‘user=’+ encodeURIComponent(‘name’) + ';expires = ’ + new
Date(0)
instanceof 的原理
instanceof 可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找
到类型的prototype
typeof 对于原始类型来说,除了null 都可以显示正确的类型
typeof 对于对象来说,除了函数都会显示object,所以说typeof 并不能准确判断变量到底是什
么类型
如果我们想判断一个对象的正确类型,这时候可以考虑使用instanceof,因为内部机制是通过原
型链来判断的
对于原始类型来说,你想直接通过instanceof 来判断类型是不行的
四:数组字符串
数组方法:
前增:unshift(新元素);后增:Push
前删:shift() ; 后删:pop
改: splice(从哪个下标开始,删除几个,新元素1,新元素2,……);
截:slice(从哪个下标开始,到哪个下标结束) ;
拼:concat(新元素)
复:截arr.slice(0):从下标为零的元素开始截;arr.concat():
增push(arr[i]):遍历原数组,在空的新数组后增加;遍历数组map
排:逆序数组:reverse()
编码值排序:sort() sort(function(a,b){return a-b;)从大到小
转:转成字符串:toString();join(‘连接符’):转为以指定字符串连接的字符串
indexOf(元素,从哪个下标开始);
查找元素,不存在返回-1:lastIndexOf(元素,从哪个下标开始向前找第一个出现的位置)
遍历数组:forEach(function(value,index,array){})
遍历数组,map 可对元素进行修改:(function(value,index,array){return …})
map 接受两个参数,第一个是回调函数,第二个控制回调函数中this 的指向;
需要return
Map 里面放一个方法,然后是一个参数,参数就是每一个数组的元素。记得map
里面放的是一个方法。
过滤器:filter
归并:reduce(function(prev,next,index,array){return …}) 归并
除slice(截)、concat(拼)、tostring,join(转)、es6 新增的都会影响新数组。
Array.from() 与Array.reduce()
*Array.from()方法
就是将一个类数组对象或者可遍历对象转换成一个真正的数组
用处:
1、将类数组对象转换为真正数组:
转换条件:1、该类数组对象必须具有length 属性,用于指定数组的长度。如果没有length
属性,那么转换后的数组是一个空数组。
2、该类数组对象的属性名必须为数值型或字符串型的数字
2、将Set 结构的数据转换为真正的数组:
Array.from 还可以接受第二个参数,作用类似于数组的map 方法,用来对每个元素进行处
理,将处理后的值放入返回的数组。
3、将字符串转换为数组:
*Array.reduce()方法
对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。
用处:
1.数组元素求和
2.二维数组转化为一维数组
3.计算数组中元素出现的次数
4.数组去重
数组去扁平化
遍历数组arr,若arr[i]为数组则递归遍历,直至arr[i]不为数组然后与之前的结果concat

  1. reduce:reduce 包含两个参数:回调函数,传给total 的初始值
  2. toString & split:调用数组的toString 方法,将数组变为字符串然后再用split 分割还原为数组
  3. join & split:将数组变为字符串然后再用split 分割还原为数组
  4. 递归:递归的遍历每一项,若为数组则继续遍历,否则concat
  5. 扩展运算符,es6 的扩展运算符能将二维数组变为一维,遍历,若arr 中含有数组则使用一次
    扩展运算符,直至没有为止。
    6:Array.flat(n):n 代表维度,拉平几层
    数组去重
    1:利用ES6 Set 去重
    2:利用for 嵌套for,然后splice 去重双层循环,外层循环元素,内层循环时比较值。值相
    同时,则删去这个值。
    3:利用indexOf 去重新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前
    元素,如果有相同的值则跳过,不相同则push 进数组。
    4:利用sort() 利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。
    5:利用filter 使用ES6 中的Array.filter() 遍历数组,并结合indexOf 来排除重复项
    6:利用递归去重
    7:利用Map 数据结构去重: 创建一个空Map 数据结构,遍历需要去重的数组,把数组的每
    一个元素作为key 存到Map 中。由于Map 中不会出现相同的key 值,
    所以最终得到的就是去重后的结果。
    8:利用reduce
    9:new Set()
    判断数组
    1:instanceof : 通过判断对象的原型链中是不是能找到类型的prototype。
    2:Array.isArray():用来判断对象是否为数组(ES5 新增的方法).当检测Array 实例时,Array.isArray
    优于instanceof ,因为Array.isArray 可以检测出iframes.
    3:Object.prototype.toString.call()
    该方法可以很好地区分各种类型,甚至是null 和undefined , 除了自定义对象类型(这个可
    用instanceof 区分)。
    4:constructor:和instanceof 原理差不多。需要事先知道待判断的对象大概属于何种类型,所
    以该方法更准确地说,是用来验证的。如果我们事先根本不知道一个对象实例的出处,那就不好
    使了。
    深度遍历、广度遍历
    深度优先就是自上而下的遍历搜索广度优先则是逐层遍历,
    深度优先不需要记住所有的节点, 所以占用空间小, 而广度优先需要先记录所有的节点占用空间

    深度优先有回溯的操作(没有路走了需要回头)所以相对而言时间会长一点
    深度优先采用的是堆栈的形式, 即先进后出
    广度优先则采用的是队列的形式, 即先进先出
    String 字符串方法(查、替、截、转)
    indexOf(‘字符串’,从哪个下标开始查找)
    charAt(下标) :根据下标查找字符。
    charCodeAt(下标) : 根据下标查找字符的编码。
    replace(旧串,新串):替
    substring(start,end):截
    substr(start,length)
    slice(start,end);
    split(‘切割符’,length):转
    作用域
    理解:作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量
    只能向上访问,变量访问到window 对象即被终止,
    作用域链向下访问变量是不被允许的。
    作用域: 起作用的一块区域
    作用域的概念: 对变量起保护作用的一块区域
    作用: 作用域外部无法获取到作用域内部声明的变量,作用域内部能够获取到作用域外界
    声明的变量。
    分类:块作用域、词法作用域、动态作用域js 属于语法作用域(函数作用域)
    require 与import 的区别
    第一、两者的加载方式不同,require 是在运行时加载,而import 是在编译时加载
    第二、规范不同,require 是CommonJS/AMD 规范,import 是ESMAScript6+规范
    第三、require 特点:社区方案,提供了服务器/浏览器的模块加载方案。非语言层面的标准。
    只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。
    import 特点:语言规格层面支持模块功能。支持编译时静态分析,便于JS 引入宏和类型检
    验。动态绑定。
    window.onload 与document.ready 的区别?
    1.执行时间
    window.onload 必须等到页面内包括图片的所有元素加载完毕后才能执行。
    $(document).ready()是DOM 结构绘制完毕后就执行,不必等到加载完毕。
    2.编写个数不同
    window.onload 不能同时编写多个,如果有多个window.onload 方法,只会执行一个
    $(document).ready()可以同时编写多个,并且都可以得到执行,
    3.简化写法
    window.onload 没有简化写法
    ( d o c u m e n t ) . r e a d y ( f u n c t i o n ( ) ) 可 以 简 写 成 (document).ready(function(){})可以简写成 (document).ready(function())(function(){});
    实现延迟加载:
    Settimeout
    Async: script 标签加上:直接异步
    Window.onload
    JavaScript 中如何检测一个变量是一个String 类型
    三种方法(typeof、constructor、Object.prototype.toString.call())
    typeof(‘123’) === “string” // true
    ‘123’.constructor === String // true
    Object.prototype.toString.call(‘123’) === ‘[object String]’ // true
    js 去除字符串空格
    replace 正则匹配方法、str.trim()方法、JQ 方法:$.trim(str)方法
    去除字符串内所有的空格:str = str.replace(/\s*/g,"");
    trim()方法是用来删除字符串两端的空白字符并返回,trim 方法并不影响原来的字符串本身,它
    返回的是一个新的字符串。
    缺陷:只能去除字符串两端的空格,不能去除中间的空格
    $.trim()函数会移除字符串开始和末尾处的所有换行符,空格(包括连续的空格)和制表符。如果这
    些空白字符在字符串中间时,它们将被保留,不会被移除。
    js 数据类型
    值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、
    Symbol。
    引用数据类型:对象(Object)、数组(Array)、函数(Function)。
    创建对象方法:字面量、构造函数、Object.creat
    js 数据对象
    Js 创建对象
    工厂模式
    特点:1、用函数来封装,并以特定接口创建对象;2、有返回值
    缺点:虽然解决了创建多个对象的问题,但没有解决对象识别的问题(怎样知道一个对象的类型)
    构造函数模式(通过this 实现)
    用构造函数可以创建特定类型的对象,同时也可以创建自定义的构造函数,从而定义自定义对象类型
    的属性和方法。
    与工厂模式的区别在于:
    1、没有显式地创建对象;
    2、直接将属性和方法赋给了this 对象
    3、没有return 语句
    原型模式(通过原型对象实现)
    创建的每个函数都有一个prototype 属性,这个属性是一个指针,指向一个对象,而这个对象包
    含了所有实例共享的属性和方法。因此可以将属性和方法放在原型对象里面,让所有实例都可以共享。
    先新建一个空的构造函数,然后将属性和方法添加到原型对象里面,再创建实例对象,实例对象
    就拥有了原型对象里的属性和方法。不管创建多少个实例对象,原型对象里的属性和方法都是共享的。
    组合使用构造函数模式原型模式
    构造函数模式用来定义实例属性,原型模式用来定义方法和共享的属性。
    动态原型模式
    通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。
    寄生构造函数模式
    基本思想:创建一个函数,其作用是封装创建对象的代码,然后返回新创建的对象。
    稳妥构造函数模式
    稳妥对象,指的是没有公共属性,而且其方法也不引用this 的对象。稳妥对象最适合在一些安全的环
    境中(这些环境会禁止使用this 和new),或者在防止数据被其他应用程序改动时使用。
    其与寄生构造函数不同之处:1、新创建对象的实例方法不引用this;2、不使用new 操作符调用构造
    函数
    js 继承(口述代码)
    1、原型链继承
    // 父类
    function Person() {}
    // 子类
    function Student(){}
    // 继承
    Student.prototype = new Person()
    2、构造函数式继承
    // 父类
    function Person() {
    this.hobbies = [‘music’,‘reading’]
    }
    // 子类
    function Student(){
    Person.call(this) // 新增的代码
    }
    3、组合式继承
    // 父类
    function Person() {
    this.hobbies = [‘music’,‘reading’]
    }
    // 父类函数
    Person.prototype.say = function() {console.log(‘I am a person’)}
    // 子类
    function Student(){
    Person.call(this) // 构造函数继承(继承属性)
    }
    // 继承
    Student.prototype = new Person() // 原型链继承(继承方法)
    4、原型式继承
    5、寄生式继承
    6、寄生组合式继承
    原型链:
    通过一个对象的proto可以找到它的原型对象,原型对象也是一个对象,就可以通过原型对象
    proto, 最后找到了我们的Object.prototype,从实例的原型对象开始一直到Object.prototype
    就是我们的原型链。
    原型:
    实例在被创建的那一刻,构造函数的prototype 属性的值
    作用:实现资源共享
    原型链的基本原理:
    任何一个实例,通过原型链,找到它上面的原型,该原型对象中的方法和属性,可以被所有
    的原型实例共享。
    javascript 的typeof 返回哪些数据类型
    7 种分别为string、boolean、number、Object、Function、undefined、symbol(ES6)
    闭包
    概念
    闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以函数执行完毕不会被回收,
    因此可以用来封装一个私有变量,通过保护变量的安全实现JS 私有属性和私有方法,避免全局污染
    特征
    1.函数嵌套函数
    2.内部函数可以访问外部函数的变量
    3.参数和变量不会被回收
    4.容易造成内存泄漏
    作用
    变量私有化
    避免全局污染
    原理
    利用了Javascript 中的垃圾回收机制,当前一个函数调用结束时,这个函数包括里面的局部变量
    都将会被垃圾回收机制进行回收释放,回收的过程中,如果发现局部变量正在被其它函数使用,则这
    个局部变量将不会被释放,而是永久保存在内存中,以供其它地方使用
    Javascript 中的垃圾回收机制
    标记清除:
    定义和用法:
    当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:“离开环境”。某一个
    时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收
    的变量。到目前为止,IE、Firefox、Opera、Chrome、Safari 的js 实现使用的都是标记清除的垃圾回
    收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。
    引用计数:
    定义和用法:引用计数是跟踪记录每个值被引用的次数。
    基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0 时,被视为准备回收的对
    象。
    内存泄漏:
    内存泄漏memory leak :
    指任何对象在您不再拥有或需要它之后仍然存在
    1:垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用
    数量为0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可
    回收。
    2:setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
    3:闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
    JS 哪些操作会造成内存泄露
    1:意外的全局变量引起的内存泄露
    2:闭包引起的内存泄露
    3:没有清理的DOM 元素引用
    4:被遗忘的定时器或者回调
    5:子元素存在引起的内存泄露
    6:IE7/8 引用计数使用循环引用产生的问题
    面向对象和面向过程的异同
    面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的
    时候一个一个依次调用就可以了。
    面向过程是一种自顶向下的编程。
    面向过程优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;
    比如单片机、嵌入式开发、Linux/Unix 等一般采用面向过程开发,性能是最重要的因素。
    缺点:没有面向对象易维护、易复用、易扩展
    面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是
    为了描叙某个事物在整个解决问题的步骤中的行为。
    面向对象是将事物高度抽象化。面向对象必须先建立抽象模型,之后直接使用模型就行了。
    优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出
    低耦合的系统,使系统更加灵活、更加易于维护
    缺点:性能比面向过程低
    null 和undefined 的区别?
    undefined 是一个表示"无"的原始值,转为数值时为当声明的变量还未被初始化时,变量的默认
    值为null 用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
    BOM 对象
    1、window 对象,是JS 的最顶层对象,其他的BOM 对象都是window 对象的属性;
    2、document 对象,文档对象;
    3、location 对象,浏览器当前URL 信息;
    4、navigator 对象,浏览器本身信息;
    5、screen 对象,客户端屏幕信息;
    6、history 对象,浏览器访问历史信息;
    DOM 事件模型:
    事件捕获:自上而下;
    事件冒泡:自下(目标元素)而上
    DOM 事件流:
    事件捕获,目标阶段,事件冒泡
    event
    阻止默认事件:event.preventDefault();
    阻止事件冒泡:event.stopPropagation();event.cancelBubble = true;
    事件委托: event.currentTarget (当前所绑定的事件对象,父元素)
    event.target(当前被点击的元素,子元素)
    常用浏览器内核(Layout Engine),兼容性前缀?
    移动端:安卓–谷歌-webkit
    内核:
    IE 浏览器的内核Trident;
    Mozilla 的Gecko;
    Chrome 的Blink(WebKit 的分支);
    Opera 内核原为Presto,现为Blink;
    前缀:
    html5 新特性h5 新特性
    1:新的语义标签和属性section article header nav figure main
    2:表单新特性
    3:视频和音频
    4:Canvas 绘图
    5:SVG 绘图
    6:地理定位
    7:拖放API
    Localstory
    缓存清单(离线缓存):minifast
    css 选择器优先级
    内联(1000);id(0100) ;class 类、伪类(0010) ;标签(0001);后代、子代选择符是所有选
    择符之和
    实现三角形:
    .triangle{
    width:0;
    height:0;
    border-width:20px;
    border-style:solid dashed dashed dashed;
    border-color:#e66161 transparent transparent transparent;
    }
    直角梯形
    只需要将上边框取消,左右选取一个将其颜色置为透明
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid yellow;
    border-bottom: 50px solid blue;
    普通梯形
    普通梯形的上边框需要使用width 属性指定,要给他一定的宽度
    width: 25px;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 50px solid blue;
    菱形
    将正方形旋转45 度。
    width: 0;
    height: 0;
    border-top: 50px solid red;
    border-left: 50px solid black;
    border-right: 50px solid yellow;
    border-bottom: 50px solid blue;
    transform: rotate(45deg);
    平行四边形
    借助transform 中的skew 属性来实现,由于直接在div 中使用,会导致内部的字体也会相应的倾斜,
    一种解决方案是对里面的文本加一个反向的倾斜,另一种解决方案是利用为元素进行倾斜,这样内部
    的文本就不会继承倾斜了。
    爱心
    爱心可以通过的其他元素进行遮掩拼接实现。首先画一个正方形
    通过为元素画两个圆覆盖在正方形上
    旋转45 度颜色改成一致的
    css 动画特性可以用js 实现,为啥还要用css 实现
  6. 不占用JS 主线程;
  7. 可以利用硬件加速;
  8. 浏览器可对动画做优化(元素不可见时不动画,减少对FPS 的影响)。
    坏处是:
    浏览器对渲染的批量异步化处理让动画难以控制,
    定位:position
    绝对定位:absolute
    1:不占位置,脱离了文档流
    2:使用left right top bottom 等属性改变位置
    3:相对其最接近并且有定位设置的父元素进行绝对定位
    如果不存在这样的父元素则相对浏览器进行绝对定位
    4:层叠顺序通过z-index 属性定义,z-index:5(不带单位);值越大越在上
    相对定位:relative
    1:遵循正常的文档流;
    2:使用left right top bottom 等属性改变位置
    3:相对文档流中自身的位置进行偏移
    4:层叠通过z-index 属性定义,z-index:5(不带单位);值越大越在上
    固定定位:fixed
    1:不占位置,脱离了文档流
    2:使用left right top bottom 等属性改变位置
    3:参照物:浏览器的可视窗口
    4:层叠通过z-index 属性定义,z-index:5(不带单位);值越大越在上
    粘性定位:sticky
    当滚到一定距离的时候窗口就固定到某一位置
    对top bottom 比较敏感
    双飞翼布局:
    1:浮动:左侧设置左浮动,右侧设置右浮动即可,中间会自动地自适应。
    2:绝对定位
    左侧设置为绝对定位left:0px。右侧设置为绝对定位right:0px。
    中间设置为绝对定位,left 和right 都为300px,即可。中间的宽度会自适应。
    3:flexbox 布局
    将左中右所在的容器设置为display: flex,设置两侧的宽度后,然后让中间的flex = 1,即可。
    4:表格布局table
    设置整个容器的宽度为100%,设置三个部分均为表格,然后左边的单元格为300px,
    右边的单元格为300px,即可。中间的单元格会自适应。
    CSS Flex 和Grid flex 布局
    Flex 主要用于一维布局,而Grid 则用于二维布局
    1:flex(弹性布局) 容器中存在两条轴, 横轴和纵轴, 容器中的每个单元称为flex item。
    在容器上可以设置6 个属性:
  • flex-direction 定义主轴
  • flex-wrap 是否换号
  • flex-flow 前两个简写
  • justify-content 主轴对其方式
  • align-items 交叉轴对齐方式
  • align-content
    Flex 项目属性
    有六种属性可运用在item 项目上:
  1. order 项目排列顺序
  2. flex-basis
  3. flex-grow 项目放大比例
  4. flex-shrink 项目缩小比例
  5. flex
  6. align-self
    注意:当设置flex 布局之后,子元素的float、clear、vertical-align 的属性将会失效
    2:Grid
    CSS 网格布局用于将页面分割成数个主要区域,或者用来定义组件内部元素间大小、位置和图层之间
    的关系。像表格一样,网格布局让我们能够按行或列来对齐元素。但是,使用CSS 网格可能还是比
    CSS 表格更容易布局。例如,网格容器的子元素可以自己定位,以便它们像CSS 定位的元素一样,
    真正的有重叠和层次。
    文本超出部分显示省略号
    单行
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    多行
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3; // 最多显示几行
    overflow: hidden;
    移动端适配
    使用媒体查询做的响应式布局,根据不同屏幕宽度加载不同css.
    垂直居中一个元素
    1:已知元素高宽:
    父元素相对定位,当前元素绝对定位居中, top,left50% ; margin-top:margin-left: 宽高
    50%;
    2:未知元素的高宽
    1:父元素相对定位,当前元素绝对定位居中, top,left50% ; transform: translate(-50%,
    -50%); 在水平和垂直方向上各偏移-50%
    2:父元素相对定位,当前元素绝对定位居中,top,left,right,bottom:0 让四个定位属
    性都为0 ,在设置margin: 0 auto
    3:弹性盒子:设置外层盒子display 为flex,设置内层盒子的垂直,水平居中,align-items:
    center,justify-content: center
    3:img 居中
    display: table-cell;
    text-align: center;
    vertical-align: middle;
  7. 将容器设为display:table 让他成为一个块级表格元素,子元素display:table-cell 使子元素成为表
    格单元格,然后就像在表格里一样,给子元素加个vertical-align: middle 就行了,多行文字垂直居中
    2.弹性盒display:flex; align-items:center;justify-content:center
    3.伪元素.father:before{content:".";display:inline-block; vertical-align:middle; height:100%;}
  8. 绝对定位+transform 反向偏移。position:absolute; transform:translate(-50%,-50%);
  9. 已知宽度高度(position:absolute; left:0; top:0; right:0; bottom:0; margin:auto)
  10. 绝对定位+margin 反向偏移position:absolute; left:50%; top:50%; margin-left:-100px;
    margin-top:-50px;
    @import link 区别:
    1:本质区别,link 是html 标签,@import 是css 提供的一种方式
    2:加载顺序:link 是和标签同时加载,@import 是后加载
    3:兼容性: link 兼容性好
    4:js 的dom 操作中只能用link 中的样式
    盒模型:
    标准盒模型(box-sizing: content-box;width 和height 指的是内容区域的宽度和高度)
    IE 盒模型(box-sizing: border-box;width 和height 指的是内容区域+border+padding 的宽度和高
    度。)
    HTML、JavaScript、CSS、Java、PHP、Python 的注释代码形式。代码注释
    HTML 的注释方法:
    CSS 的注释方法:/* 注释内容*/
    JavaScript 注释:1.//单行备注2./注释内容/(多行注释)
    PHP/Java:单行: // 多行: /* /
    python:单行: # 多行: “”" “”" 多行: ‘’’ ‘’’’
    解决高度塌陷问题(清除浮动的方法):
    1:在浮动元素下方加一个空div 并且添加样式clear:both
    原理:clear:both;忽略以上浮动元素所预留出来的两侧的空间。
    缺点:产生不必要的元素、造成代码的冗余。
    2:给浮动元素的父元素添加overflow:hidden
    原理:触发了bfc,计算bfc 高度里面的浮动元素也参与了计算。
    缺点:会隐藏溢出的元素;
    3:万能清除法
    css 样式中.标签名::after{
    content:"";
    display:block;
    clear:both;}
    css 样式中.标签名::after{
    content:" . ";
    display:block;
    height:0;
    clear:both;
    visibility:hidden;
    }
    为了兼容ie6 ie7 后面还需加.标签名{zoom:1;}
    margin 塌陷/margin 重叠
    竖直方向的margin 不叠加,只取较大的值作为margin 解决办法:触发BFC
    bfc:
    1:一个独立容器,容器里面的子元素不会影响到外面的元素
    2:内部的子元素,在垂直方向,边距会发生重叠
    3:BFC 区域不与旁边的float box区域重叠,
    4:计算BFC 的高度时,浮动的子元素也参与计算
    触发BFC 方法:
    1:overflow: hidden、auto。
    2:float 的属性值不为none
    3:posiiton:absolutefixed4:display 为inline-block, table-cell, table-caption, flex, inline-flex DOCTYPE: 声明文档类型,共三种:HTML 4.01 中有两种写法,一种是严格的,一种是传统的,HTML 5 的写法是`。
    rgba()和opacity
    rgba()和opacity 都能实现透明效果, opacity 作用于元素,以及元素内的所有内容的透明度,
    rgba()只作用于元素的颜色或其背景色。(设置rgba 透明的元素的子元素不会继承透明效果!)
    web 标准
    不是某一个标准,而是一系列标准的集合。网页主要由三部分组成:结构(Structure)、表现
    (Presentation)和行为(Behavior)。对应的标准也分三方面:结构化标准语言主要包括XHTML 和
    XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如W3C DOM)、ECMAScript 等。这
    些标准大部分由万维网联盟(外语缩写:W3C)起草和发布,也有一些是其他标准组织制订的标准,
    比如ECMA(European Computer Manufacturers Association)的ECMAScript 标准。
    让一个div 元素隐藏隐藏元素
    1.display:none;
    2.visibility:hidden;
    3.background-color:transparent;或者设成与背景一样的颜色即可
    4.opacity 来设置不透明级别,注意兼容性filter…
    5.给div 一个margin 负值,这个负值恰好等于div 自身的高度或宽度
    6.设置两个大小一样的div,第一个左浮动,第二个不浮动,即可将第二个div 隐藏
    7.设置一个父div 和一个子div,子div 绝对定位,父div 相对定位,子div 的left 就是子div 的宽度
    8.将div 的宽度和高度设置为0
    .rem 和em 的区别?
    em 相对于父元素,rem 相对于根
    px:固定单位
    em:相对单位相对于父元素的font-size 值
    rem:相对单位相对于html 的font-size 值的变化而变化
    Rem:自适应方案,对于WebApp 来说,为了更通用地满足各机型屏幕的自适应布局要求,我们目
    前采用rem 布局方案。
    dpr 设备像素密度比:
    物理像素:设备实际显示的像素
    逻辑像素:css 设置的像素
    浏览器兼容
    1:ie 下图片加超链接会有边框:解决办法:img{border:0;}
    2:在元素中直接插入图片时,图片会产生3px 间隙
    解决办法:1:img{display:block;} 2:img{vertical-aline:bottom/top/middle;只要不为baseline 3:浮动
    3:在IE6 及以下版本中,部分块元素拥有默认高度(低于16px 高度)
    解决办法:1:给元素添加声明:font-size:0; 2:给元素添加声明:overflow:hidden;
    4:在IE6 及以下版本中在解析百分比时,会按四舍五入方式计算从而导致50%加50%大于100%
    的情况解决办法:右面的浮动元素添加声明:clear:right;
    5:表单元素行高对齐方式不一致解决办法:给表单元素添加声明:float:left;或vertical-align:top;
    6:当给LI 里的A 转成块元素,并设置了固定高度时,且给父元素写了浮动后在IE6 及更低的
    版本浏览器里会出现垂直显示。解决办法:给a 也设置左浮动。
    7:透明
    兼容
    //1. 滚动条距离顶端的距离(谷歌)
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    //2. 滚动条距离左端的距离(谷歌)
    var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
    //3. byClassName 的兼容(ie9 以下)
    function byClassName(obj, className) {
    if (obj.getElementsByClassName) { //支持
    return obj.getElementsByClassName(className);
    } else { //不支持
    var eles = obj.getElementsByTagName(’
    ’); //获取所有的元素
    var arr = [];
    //遍历每一个元素,找出符合条件的元素放到新数组中。
    for (var i = 0, len = eles.length; i < len; i++) {
    if (eles[i].className === className) {
    arr.push(eles[i]);
    }
    }
    return arr;
    }
    }
    //4.获取非行内样式的兼容
    //获取非内行样式的兼容
    function getStyle(obj, attr) {
    //return window.getComputedStyle ? getComputedStyle(obj,true)[attr] : obj.currentStyle[attr];
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr];
    }
    //5. 获取事件对象的兼容
    var e = evt || window.event;
    //6. event.button 的兼容
    function getButton(evt) {
    var e = evt || window.event;
    if (evt) {
    return e.button;
    } else if (window.event) {
    switch (e.button) {
    case 1:
    return 0;
    case 4:
    return 1;
    case 2:
    return 2;
    }
    }
    }
    //7. 获取键盘按钮的编码值的兼容onkeypress
    event.keyCode || event.charCode || event.which
    //8. 阻止事件冒泡的兼容
    e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
    //9. 阻止浏览器默认行为的兼容
    e.preventDefault ? e.preventDefault() : e.returnValue = false;
    //10. 添加事件监听器的兼容
    function addEventListener(obj, event, fn, boo) {
    boo = boo || false;
    if (obj.addEventListener) {
    obj.addEventListener(event, fn, boo);
    } else if (obj.attachEvent) {
    obj.attachEvent(‘on’ + event, fn);
    }
    }
    //11. 移除事件监听器的兼容
    function removeEventListener(obj, event, fn, boo) {
    boo = boo || false;
    if (obj.removeEventListener) {
    obj.removeEventListener(event, fn, boo);
    } else if (obj.detachEvent) {
    obj.detachEvent(‘on’ + event, fn);
    }
    }
    //12. 获取事件源的兼容
    var target = e.target || e.srcElement;
    浏览器的缓存机制
    数据请求可以分为发起网络请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们
    在第一和第三步骤中优化性能。比如说直接使用缓存而不发起请求,或者发起了请求但后端存储的数
    据和前端一致,那么就没有必要再将数据回传回来,这样就减少了响应数据。
    强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome 控制台的Network 选项中可以
    看到该请求返回200 的状态码,并且Size 显示from disk cache 或from memory cache。强缓存可
    以通过设置两种HTTP Header 实现:Expires 和Cache-Control。
    协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定
    是否使用缓存的过程,主要有以下两种情况:
    强制缓存优先于协商缓存进行,若强制缓存(Expires 和Cache-Control)生效则直接使用缓存,若不生效
    则进行协商缓存(Last-Modified / If-Modified-Since 和Etag / If-None-Match),协商缓存由服务器决定是否
    使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再
    存入浏览器缓存中;生效则返回304,继续使用缓存
    状态码200 304 区别
    其实, 200 OK (from cache) 是浏览器没有跟服务器确认,直接用了浏览器缓存;而304 Not
    Modified 是浏览器和服务器多确认了一次缓存有效性,再用的缓存。200(from cache) 是速度最快的,
    因为不需要访问远程服务器,直接使用本地缓存.304 的过程是, 先请求服务器, 然后服务器告诉我们
    这个资源没变, 浏览器再使用本地缓存.
    浏览器渲染原理:
    1:将HTML 解析成一个DOM 树,
    2:将CSS 解析成CSS Rule Tree;
    3:根据DOM 树和CSSOM 来构造Rendering Tree
    4:layout:计算出每个节点在屏幕中的位置
    5:绘制:遍历render 树,并使用UI 后端层绘制每个节点
    服务端渲染和前端渲染:
    服务器渲染(后端渲染)
    浏览器发送请求到服务器端,服务器端处理请求并处理好数据,然后生成html 文件,并返回给浏览
    器。传统的jsp、php 都是属于服务器渲染。
    客户端渲染(前端渲染)
    服务器端处理请求后将数据返回给浏览器,浏览器通过拼接html 字符串或者使用js 模板引擎,或者
    React 这类框架进行页面渲染,又称作: 局部渲染
    前端渲染的优势:
    局部更新页面,无需每次都进行完整页面请求
    懒加载。页面初始时只加载可视区域内的数据,随着滚动等操作再加载其他数据
    节约服务器成本
    关注分离设计。服务器只用于访问数据库提供接口,前端关注展现。
    富交互,使用JS 实现各种酷炫效果
    前端渲染从ajax 将数据请求,由浏览器通过拼接html 字符串或者使用js 模板引擎,或者React 这类
    框架进行页面渲染,,这样服务端压力比较小,这样不利于su 优化
    服务端渲染是由服务器处理请求并处理好数据,然后生成html 文件,并返回给浏览器。传统的jsp、
    php 都是属于服务器渲染。所有处理有服务器处理完成,页面打开速度将会非常快,有利于su 优化,
    因为是由服务端拼接好模板,所以爬虫将会拿到页面所有内容。
    重排、回流(reflow)和重绘(Repaint)?
    回流:
    DOM 节点中的各个元素都有自己的盒子(模型),根据各种样式来计算,并根据计算结果将元
    素放在它该出现的位置
    触发:
    增删改DOM 节点时;移动DOM 的位置;
    修改CSS 样式时(宽高、display 为none 等);
    修改网页的默认字体时;避免:触发动画的开始不要用diaplay:none 属性值;translate 属性
    值来替换top/left/right/bottom 的切换;
    scale 属性值替换width/height;opacity 属性替换display/visibility
    重绘:
    当页面元素样式改变不影响元素在文档流中的位置时(如background-color,border-color,
    visibility),浏览器只会将新样式赋予元素并进行重新绘制操作。
    回流必定重绘,重绘不一定回流
    避免大量页面回流的手段也有很多,其本质都是尽量减少引起回流和重绘的DOM 操作
    如何尽量减少Repaint 的频率?
    如果需要创建多个DOM 节点,可以使用DocumentFragment创建完,然后一次性地加入
    document;将元素的display 设置为”none”,完成修改后再把display 修改为原来的值
    重绘是当节点需要更改外观而不会影响布局的,比如改变color 就叫称为重绘
    回流是布局或者几何属性需要改变就称为回流。
    回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变父节点里的
    子节点很可能会导致父节点的一系列回流。
    如何避免回流,重绘:
    减少回流、重绘其实就是需要减少对render tree 的操作,并减少对一些style 信息的请求。
    1.避免操作DOM,创建一个div,在它上面应用所有DOM 操作,最后将他添加到window.document
    ;或者在一个display:none 的元素上进行操作,最终把它显示出来。因为display:none 上的DOM 操作
    不会引发回流和重绘。
  11. 尽可能在DOM 树的末端改变class 可以限制回流的范围,使其影响尽可能少的节点。
  12. 让要操作的元素进行"离线处理",处理完后一起更新,这里所谓的"离线处理"即让元素不存在于
    render tree 中。如读取offsetLeft 等属性。
  13. 避免设置多层内联样式,因为每一个都会造成回流,样式合并在一个外部类,这样当该元素的class
    属性被操作时,只会产生一个reflow。
  14. 将需要多次回流的元素position 属性设为absolute 或fixed,这样该元素就会脱离文档流,它的变
    化不会影响其他元素变化。比如动画效果应用到position 属性为absolute 或fixed 的元素上。
  15. 避免使用table 布局
    函数防抖与函数节流
    函数防抖:就是指触发事件后在n 秒内函数只能执行一次,如果在n 秒内又触发了事件,则会
    重新计算函数执行时间。(当一个动作连续触发,则只执行最后一次),
    函数防抖应用场景:搜索框搜索输入。只需用户最后一次输入完,再发送请求
    手机号、邮箱验证输入检测
    窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
    函数节流:限制一个函数在一定时间内只能执行一次。
    函数节流应用场景:滚动加载,加载更多或滚到底部监听
    谷歌搜索框,搜索联想功能
    高频点击提交,表单重复提交
    函数防抖,将多次执行的事件合并成一次。函数节流,保持一段时间执行一次。
    函数节流实现方法:定时器
    时间戳:通过比对上一次执行时间与本次执行时间的时间差与间隔时间的大
    小关系,来判断是否执行函数。若时间差大于间隔时间,则立刻执行一次函数。并更新上一次执行时
    间。
    二者:都可以通过使用setTimeout 实现。目的都是,降低回调执行频率。节省计算资源。
    事件代理
    事件代理(Event Delegation),又称之为事件委托。是JavaScript 中常用绑定事件的常用技
    巧。
    顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听
    的职务。
    事件代理的原理是DOM 元素的事件冒泡。使用事件代理的好处是可以提高性能。
    进程及线程
    进程描述了CPU 在运行指令及加载和保存上下文所需的时间,放在应用上来说就代表了一
    个程序。线程是进程中的更小单位,描述了执行一段指令所需的时间。当你打开一个Tab 页时,
    其实就是创建了一个进程,一个进程中可以有多个线程,比如渲染线程、JS 引擎线程、HTTP 请
    求线程等等。当你发起一个请求时,其实就是创建了一个线程,当请求结束后,该线程可能就会
    被销毁。
    宏任务微任务
    一个宏任务中包含多个微任务,宏任务的优先级高于微任务,在当前的微任务没有执行完成时,
    是不会执行下一个宏任务的。
    微任务:process.nextTick,promise,Object.observe,MutationObserver
    宏任务:script,setTimeout,setInterval,setImmediate,I/O,UI rendering
    Event loop 顺序
    执行同步代码,这属于宏任务
    执行栈为空,查询是否有微任务需要执行
    执行所有微任务
    必要的话渲染UI
    然后开始下一轮Event loop,执行宏任务中的异步代码
    操作DOM 性能很差,原因
    DOM 是属于渲染引擎中的东西,而JS 又是JS 引擎中的东西。当我们通过JS 操作DOM 的时
    候,其实这个操作涉及到了两个线程之间的通信,那么势必会带来一些性能上的损耗。操作DOM 次
    数一多,也就等同于一直在进行线程之间的通信,并且操作DOM 可能还会带来重绘回流的情况,
    所以也就导致了性能上的问题。
    为什么虚拟dom 会提高性能?(必考)
    虚拟dom 相当于在js 和真实dom 中间加了一个缓存,利用dom diff 算法避免了没有必要的
    dom 操作,从而提高性能。
    用JavaScript 对象结构表示DOM 树的结构;然后用这个树构建一个真正的DOM 树,插到文
    档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树
    差异把2 所记录的差异应用到步骤1 所构建的真正的DOM 树上,视图就更新了。
    插入几万个DOM,如何实现页面不卡顿?
    不能一次性把几万个DOM 全部插入,否则肯定卡顿,应该分批次部分渲染dom,通过
    requestAnimationFrame 的方式去循环的插入DOM 或者虚拟滚动(virtualized scroller)。只渲染可视
    区域内的内容,非可见区域的那就完全不渲染了,当用户在滚动的时候就实时去替换渲染的内容
    Virtual DOM
    virtual-dom 是一种利用JavaScript 构建dom 的技术,主要解决了复杂应用程序的维护程度。
    工作过程:
    1)每当底层数据发生改变时,整个UI 都将在Virtual DOM 描述中重新渲
    2)然后计算之前DOM 表示与新表示的之间的差异
    3)完成计算后,将只用实际更改的内容更新real DOM
    一个页面从输入URL 到页面加载显示完成,这个过程中都发生了什么?
    浏览器根据请求的URL 交给DNS 域名解析,找到真实IP,向服务器发起请求;
    服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
    浏览器对加载到的资源(HTML、JS、CSS 等)进行语法解析,建立相应的内部数据结构(如HTML
    的DOM);
    载入解析到的资源文件,渲染页面,完成。
    三次握手四次挥手
    三次握手
    三次握手(Three-way Handshake),是指建立一个TCP 连接时,需要客户端和服务器总共发送3
    个包。双方都能明确自己和对方的收发能力是正常的。
    第一次,客户端向服务器发送SYN 同步报文段,请求建立连接
    服务端确认了客户端有发送数据的能力。
    第二次,服务器确认收到客户端的连接请求,并向客户端发送SYN 同步报文,表示要向客户端
    建立连接
    客户端确认了服务端有接收和发送数据的能力。
    第三次,客户端收到服务器端的确认请求后,处于建立连接状态,向服务器发送确认报文
    服务端确认了客户端具有接收(和发送)数据的能力。
    (1)客户端:我要连接你了,可以吗?
    (2)服务端:嗯,我准备好了,连接我吧。
    (3)客户端:那我连接你咯
    为什么不能两次握手?
    因为这种情况下,只有服务器对客户端的起始序列号做了确认,但客户端却没有对服务器的起始
    序列号做确认,不能保证传输的可靠性。
    两次握手的话,客户端有可能因为网络阻塞等原因会发送多个请求报文,这时服务器就会建立连接,
    浪费掉许多服务器的资源
    四次挥手
    TCP 的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。
    (1)主机向服务器发送一个断开连接的请求。(不早了,我该走了)
    (2)服务器接到请求后发送确认收到请求的信号。(知道了)
    (3)服务器向主机发送断开通知(我也该走了)。
    (4)主机接到断开通知后断开连接并反馈一个确认信号(嗯,好的),服务器收到确认信号后
    断开连接。
    为什么连接的时候是三次握手,关闭的时候却是四次握手?
    因为当Server 端收到Client 端的SYN 连接请求报文后,可以直接发送SYN+ACK 报文。其中ACK
    报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当Server 端收到FIN 报文时,很可能
    并不会立即关闭SOCKET,所以只能先回复一个ACK 报文,告诉Client 端,"你发的FIN 报文我收到了
    "。只有等到我Server 端所有的报文都发送完了,我才能发送FIN 报文,因此不能一起发送。故需要
    四步握手。
    谈谈性能优化问题三方面:1:http:使用字体图标,合并精灵图, 2:资源:
    减少空标签,减少DOM 操作,首屏之外图片按需加载3:代码优化:删除多于空格,压缩工具
    尽量减少HTTP 请求个数
    合并静态资源
    使用svg 或者字体图标
    首屏之外的图片资源按需加载
    资源丢失
    避免空的src 和href,与404
    较少DOM 操作
    强制缓存
    为文件头指定Expires 或Cache-Control ,使内容具有缓存性。
    能用css 做的效果,不要用js 做,能用原生js 做的,不要轻易去使用第三方插件
    利用h5 的新特性(localStorage、sessionStorage)做一些简单数据的存储
    图片:减少像素点
    减少每个像素点能够显示的颜色
    修饰图片用CSS 去代替。
    移动端图片用CDN 加载
    小图使用base64 格式
    将多个图标文件整合到一张图片中(雪碧图)
    选择正确的图片格式:
    函数节流函数防抖
    预加载:资源不马上用,希望尽快取得。声明式的fetch ,强制浏览器请求资源,并且不会阻塞
    onload 事件,
    预渲染:通过预渲染将下载的文件预先在后台渲染,
    懒执行:将某些逻辑延迟到使用时再计算。懒执行需要唤醒,可以通过定时器或者事件的调用来
    唤醒。
    懒加载:将不关键的资源延后加载
    如果你接到一个项目如何从头开始的项目从头开始项目开始新项目
    1:需求,确定甲方的项目目标、目标用户,当前资源(微信公众号、APP、微信号、微信群,
    把数据量化),硬性资源、软性资源、背书等等
    2:技术选型,
    3:技术环境,
    4:依赖哪些组件
    正式开始
    下载demo 文件
    在mydemo 下安装依赖
    安装模块
    运行文件
    严格模式
    变量必须声明后再使用
    函数的参数不能有同名属性,否则报错
    不能使用with 语句
    不能对只读属性赋值,否则报错
    不能使用前缀0 表示八进制数,否则报错
    不能删除不可删除的属性,否则报错
    不能删除变量delete prop,会报错,只能删除属性delete global[prop]
    eval 不会在它的外层作用域引入变量
    eval 和arguments 不能被重新赋值
    arguments 不会自动反映函数参数的变化
    不能使用arguments.callee
    不能使用arguments.caller
    禁止this 指向全局对象
    不能使用fn.caller 和fn.arguments 获取函数调用的堆栈
    增加了保留字(比如protected、static 和interface)
    优雅编程:
    工具约束产出高质量编程命名规范,注释
    面向对象到组件化的前端演进之路
    组件该如何阻止才能高效的为技术怨怼提效
    形成自己的技术思考闭环
    前端页面受到的攻击有哪些
    XSS (Cross Site Script) ,跨站脚本攻击、
    1:对用户的所有输入数据进行检测;
    2:用HtmlEncoder 等工具先对数据进行编码,然后再输出到目标页面中
    CSRF(Cross Site Request Forgery),跨站点伪造请求、
    1:验证码
    2:利用Token。当向服务器传参数时,带上Token。这个Token 是一个随机值,并且由服务器和
    用户同时持有。当用户提交表单时带上Token 值,服务器就能验证表单和session 中的Token 是否一
    致。
    cookie 劫持,通过获取页面的权限,
    点击劫持
    点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过iframe 嵌套的方式嵌入自
    己的网页中,并将iframe 设置为透明,在页面中透出一个按钮诱导用户点击
    前端好代码
    高复用低耦合,好维护,好扩展。
    前端语义化
    从广义上来说,不仅要使机器(搜索引擎等)易于理解,也要使人易于理解。在团队协作开发中,
    对人的易于理解显得尤为重要了,一个莫名其妙的class 会让后续的开发或者维护者一头雾水,增
    加了协作成本。就是在完成任务的同时,尽可能地利用标签、class、id 去让更多的人或机器来更好
    的理解我们的代码
    前端模块化
    模块化:是从代码的角度来进行分析的;把一些可复用的代码,抽离为单个的模块;便于项目的
    维护和开发
    组件化:是从UI 界面的角度来进行分析的;把一些可服用的UI1 元素, 抽离为单独的组件;
    简述对AMD、CMD、CommonJs 的理解
    AMD/CMD/CommonJs 是JS 模块化开发的标准,目前对应的实现是RequireJs/SeaJs/nodeJs
    CommonJs 主要针对服务端,AMD/CMD 主要针对浏览器端,
    AMD 是预加载,在并行加载js 文件同时,还会解析执行该模块
    CMD 是懒加载,虽然会一开始就并行加载js 文件,但是不会执行,而是在需要的时候才执行。
    or:
    AMD(RequireJS )异步加载模块,所有的模块将被异步加载,模块加载不影响后面语句运行
    CMD(SeaJS)推崇按需加载,只有在用到某个模块的时候再去require ,并不是标准组织定义
    CommonJS module 以服务器端为第一的原则发展,选择同步加载模块,仅支持对象类型(objects)
    模块
    Es6 模块化的导入:import,导出export.default;ES5 模块化的导入:require,导出module.export
    mongoDB 和MySQL 的区别
    MySQL 是传统的关系型数据库, MongoDB 则是非关系型数据库
    mongodb 以BSON 结构(二进制)进行存储,对海量数据存储有着很明显的优势。
    对比传统关系型数据库,NoSQL 有着非常显著的性能和扩展性优势,与关系型数据库相比,
    MongoDB 的优点有: ①弱一致性(最终一致),更能保证用户的访问速度:
    ②文档结构的存储方式,能够更便捷的获取数据。
    canvas:
    是一个可以使用脚本(通常为JavaScript)来绘制图形的HTML 元素.例如,它可以用于绘制图表、
    制作图片构图或者制作简单的(以及不那么简单的)动画.
    canvas 和SVG 的是什么以及区别
    SVG
    SVG 是一种使用XML 描述2D 图形的语言。SVG 基于XML,这意味着SVG DOM 中的每个
    元素都是可用的。您可以为某个元素附加JavaScript 事件处理器。在SVG 中,每个被绘制的图形均
    被视为对象。如果SVG 对象的属性发生变化,那么浏览器能够自动重现图形。
    Canvas
    Canvas 通过JavaScript 来绘制2D 图形。Canvas 是逐像素进行渲染的。在canvas 中,一旦
    图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新
    绘制,包括任何或许已被图形覆盖的对象。
    Convas
    依赖分辨率
    不支持事件处理器
    弱的文本渲染能力
    能够以.png 或.jpg 格式保存结果图像
    最适合图像密集型的游戏,其中的许多对象会被频繁重绘
    Svg
    不依赖分辨率
    支持事件处理器
    最适合带有大型渲染区域的应用程序(比如谷歌地图)
    复杂度高会减慢渲染速度(任何过度使用DOM 的应用都不快)
    不适合游戏应用
    node.js:
    简单的说Node.js 就是运行在服务端的JavaScript。Node.js 是一个基于Chrome JavaScript 运行
    时建立的一个平台。Node.js 是一个事件驱动I/O 服务端JavaScript 环境,基于Google 的V8 引擎,
    V8 引擎执行Javascript 的速度非常快,性能非常好。
    nodejs
    nodejs 是一个基于Chrome V8 引擎的JS 运行环境,也就是让javascript 运行在服务器(server)
    端,
    总的来说,Node.js 适合以下场景:
  16. 实时性应用,比如在线多人协作工具,网页聊天应用等。
  17. 以I/O 为主的高并发应用,比如为客户端提供API,读取数据库。
  18. 流式应用,比如客户端经常上传文件。
  19. 前后端分离
    不用考虑http 请求次数过多的问题。
    但它并不适合CPU 密集型的任务,比如人工智能方面的计算,视频、图片的处理等
    前后端分离
    优点:前端专门负责前端页面和特效的编写,后端专门负责后端业务逻辑的处理,前端追求的是
    页面美观、页面流畅、页面兼容等。后端追求的是三高(高并发、高可用、高性能)让他们各自负责
    各自的领域,让专业的人负责处理专业的事情,提高开发效率
    缺点:
    当接口发生改变的时候,前后端都需要改变
    当发生异常的时候,前后端需要联调–联调是非常浪费时间的
    webpack:
    本质上,webpack 是一个现代JavaScript 应用程序的静态模块打包器(module bundler)。当
    webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序
    需要的每个模快。
    管理依赖合并请求:处理依赖、模块化、打包
    WebPack 是一个模块打包工具,你可以使用WebPack 管理你的模块依赖,并编绎输出模块们所
    需的静态文件。它能够很好地管理、打包Web 开发中所用到的HTML、JavaScript、CSS 以及各种静态
    文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack 有对应的模块加载器。
    webpack 模块打包器会分析模块间的依赖关系,最后生成了优化且合并后的静态资源。
    Webpack 是一个现代的JavaScript 应用的静态打包工具
    它的核心就是让我们可以进行模块化开发,帮我们处理模块间的依赖关系
    将webpack 中的各种模块打包合并为一个或多个包,还可以对资源进行处理,比如scss 转css,
    图片压缩等
    他做了哪些工作
    1.依赖管理:方便引用第三方模块、让模块更容易复用、避免全局注入导致的冲突、避免重复加
    载或加载不需要的模块。
  20. 合并代码:把各个分散的模块集中打包成大文件,减少HTTP 的请求链接数
  21. 各路插件
    Webpack 打包原理
    识别入口文件, 分析代码, 获取模块依赖, 并且将代码打包为浏览器可以识别的代码
    递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所
    有这些模块打包成一个或多个bundle(包)
    Loader 和plugin 的区别:
    loader 用于加载待打包的资源,plugin 用于扩展webpack。
    webpack 过程:
    提供一个入口文件管理依赖合并请求生成包
    分析这个入口文件
    提取依赖
    获得babel 转成es5 后的兼容代码
    确定个全局标识符id
    对入口文件的依赖进行递归处理,进行上述分析,得到依赖图
    生成bundle
    将graph 的每个片段都插入一些代码, 成为{ id: [func(require, module,
    exports){ origin code}, dependenceMap]}的结构
    定义自己的依赖加载函数require
    将两部分字符串代码片段合成
    webpack 的理解,和gulp 有什么不同?
    webpack 是模块打包工具,会分析模块间的依赖关系,然后使用Loaders 处理他们,最后生成一个
    优化并且合并后的静态资源
    gulp 是前端自动化工具,能够优化前端工作流程,比如文件合并压缩
    .webpack 打包速度很慢, 为什么?怎么解决?
    模块太多
    webpck 可以配置externals 来将依赖的库指向全局变量,从而不再打包这个库
    git( GitHub 码云) 团队级的开发git
    组长: 创建一个远程的仓库
    邀请各个组员,给赋予权限
    给每一个组员创建一个分支,创建好公共的分支
    克隆仓库到本地,多复制一份出来(这一份作为我们分支的开发目录), 有的同学直接在仓库代码
    中开发,代码提交的时候,代码丢失,
    首先,当我们开发完之后,在开发目录中先做好测试,然后再去提交远程分支
    组长: 统管项目
    git 常用操作
    1)从远程库中克隆项目
    git clone 项目地址
    2)工作区到暂存区
    git add 文件名字、git add . 多个文件操作
    3)暂存区到版本区
    git commit -m"注释信息"
    4)把版本区文件上传到远程仓库
    git push origin master
    5)将远程仓库的文件拉取/下载下来
    git pull origin master
    6)查看当前历史记录、查看所有的操作记录
    git log、git reflog
    7)查看文件状态
    git status
    8)查看版本信息
    git version
    9)查看配置信息
    git config --list
    10)在当前目录新建一个Git 代码库(生成隐藏.git 文件)
    git init
    11)版本回退
    git reset --hard 版本id
    12)查看xx 文件修改了哪些内容
    git diff xx
    13)删除文件名
    git rm 文件名
    14)恢复一个文件[u
    git checkout
    15)关联一个远程库
    git remote add [远程仓库git 地址]
    16)移除关联一个远程库
    git remote remove [远程仓库git 地址]
    17)创建分支
    git branch 分支名
    18)查看分支数量
    git branch
    19)切换分支
    git checkout 分支名
    20)创建并切换分支
    git checkout -b 分支名
    21)当文件修改时切换分支
    git stash 暂存文件
    22)合并分支
    git merge
    23)合并指定分支到当前分支
    git merge [branch]
    24)查看已合并的分支
    git branch --merge
    25)查看未合并的分支
    git branch --no-merge
    26)查看远程分支
    git branch -r
    27)删除未合并的分支
    git branch -D 分支名
    28)删除已合并的分支
    git branch –
    29)删除远程分支
    git branch -d 分支名
    30)生成一个可供发布的压缩包
    git archive
    解决方案一(强制覆盖本地代码,你自己修改的代码即将被远程库的代码所覆盖)
    把你修改的代码进行备份,然后执行命令:
    git reset --hard origin/master 版本回退
    git pull
    从你备份好的文件当中把你写的代码拿过去,修改完成再进行git push
    解决方案二
    (合并远程库和你本地的代码)执行命令:
    git fetch 更新远程仓库文件
    git diff master origin/master 本地文件和远程仓库文件进行对比
    git merge origin/master 自动合并
    根据需求手动删除不必要的代码,修改完成git push 到远程仓库
    diff 算法
    什么是diff 算法
    将Virtual(虚拟) DOM 树转换成actual DOM 树的最少操作的过程,叫做diff
    主要
    分层比较
    拿旧虚拟DOM 跟新的虚拟DOM 进行比较
    Diff 操作三大策略
    tree diff
    component diff
    element diff
    宏观到微观
    tree diff
    比较结构
    component diff
    比较组件类型
    比较组件结构
    element diff
    比较id
    比较位置
    比较内容
    Diff 算法的作用是用来计算出Virtual DOM 中被改变的部分,然后针对该部分进行原生DOM 操
    作,而不用重新渲染整个页面。
    Tree Diff 是对树每一层进行遍历,找出不同,
    Component Diff 是数据层面的差异比较:如果都是同一类型的组件,按照原策略继续比较Virtual
    DOM 树即可。
    Vue
    Vue 全家桶
    vue+vue-router+vuex+axios
    1、vue:使用vue-cli,生成最基本的vue 项目
    2、vue-router:vue 项目中的路由管理插件
    3、vuex:vue 项目中的状态管理模式,也可以理解为vue 项目中的数据管理者,当应用足够简单时,
    可以使用global event bus(全局事件总线)替代
    4、axios:vue 项目中发起http 请求的插件,类似于jquery 中的ajax,相较于vue-resource 要好
    一些
    构建的vue-cli 工程都到了哪些技术,它们的作用分别是什么?
  22. vue.js:vue-cli 工程的核心,主要特点是双向数据绑定和组件系统。
  23. vue-router:vue 官方推荐使用的路由框架。
  24. vuex:专为Vue.js 应用项目开发的状态管理器,主要用于维护vue 组件间共用的一些变量和方
    法。
  25. axios( 或者fetch 、ajax ):用于发起GET 、或POST 等http 请求,基于Promise 设计。
  26. vux 等:一个专为vue 设计的移动端UI 组件库。
  27. 创建一个emit.js 文件,用于vue 事件机制的管理。
  28. webpack:模块加载和vue-cli 工程打包器。
    axios
    特点
    1:Axios 是一个基于promise 的HTTP 库,支持promise 所有的API
    2:它可以拦截请求和响应
    3:它可以转换请求数据和响应数据,并对响应回来的内容自动转换成JSON 类型的数据
    4:安全性更高,客户端支持防御XSRF
    常用方法?
    1:axios.get(url[, config]) //get 请求用于列表和信息查询
    2:axios.delete(url[, config]) //删除
    3:axios.post(url[, data[, config]]) //post 请求用于信息的添加
    4:axios.put(url[, data[, config]]) //更新操作
    vue 的原理
    是一套构建用户界面的渐进式框架。
    Vue 在声明式渲染(视图模板引擎)的基础上,可以通过添加组件系统、客户端路由、大规模状
    态管理来构建一个完整的框架。
    更重要的是,这些功能相互独立,可以在核心功能的基础上任意选用其他的部件,不一定要全部
    整合在一起。
    这也解释了vue 官方的”渐进式”说法;
    渐进式:用什么就引入什么,没有硬性规定。
    vue 优点
    低耦合。视图(View)可以独立于Model 变化和修改,一个ViewModel 可以绑定到不同的"View"
    上,当View 变化的时候Model 可以不变,当Model 变化的时候View 也可以不变。
    可重用性。你可以把一些视图逻辑放在一个ViewModel 里面,让很多view 重用这段视图逻辑。
    独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页
    面设计。
    可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel 来写。
    vue 组件
    组件是可复用的Vue 实例; 与new Vue 接收相同的选项,例如data、computed、watch、
    methods 以及生命周期钩子等。
    仅有的例外是像el 这样根实例特有的选项。并且一个组件的data 选项必须是一个函数
    原因:因为组件是用来复用的,且JS 里对象是引用关系,如果组件中data 是一个对象,那么这样
    作用域没有隔离,子组件中的data 属性值会相互影响,如果组件中data 选项是一个函数,那么每
    个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的data 属性值不会互相影响;而new
    Vue 的实例,是不会被复用的,因此不存在引用对象的问题。
    1:为什么根实例的data 是一个对象?
    答:new Vue()中只有一个data 属性,共用该data。
    2:为什么组件中的data 必须是一个函数?
    答:
    2.1)因为如果data 是一个对象,对象是引用类型,那复用的所有组件实例都会共享这些数据,就会
    导致修改一个组件实例上的数据,其他复用该组件的实例上对应的数据也会被修改。
    2.2)如果data 是一个函数,函数虽然也是引用类型,但是函数是有作用域的,函数内的变量不能被
    外部访问到,这样每个组件实例都会有个独立的拷贝同时又因为函数作用域的限制修改自己的数据时
    其他组件实例的数据是不会受到影响的
    总结:
    对象是引用类型,且没有作用域,会导致一改全改;
    函数是引用类型,但它有作用域,不会彼此受牵连。
    组件命名
    定义组件名有两种方式:
    1.kebab-case(短横线分隔命名),引用时必须也采用kebab-case;
    2.PascalCase(首字母大写命名),引用时既可以采用PascalCase 也可以使用kebab-case;
    但在DOM 中使用只有kebab-case 是有效的
    vue.cli 中怎样使用自定义组件?有遇到过哪些问题吗?
    第一步:在components 目录新建你的组件文件(smithButton.vue),script 一定要export default {
    第二步:在需要用的页面(组件)中导入:import smithButton from ‘…/components/smithButton.vue’
    第三步:注入到vue 的子组件的components 属性上面,components:{smithButton}
    第四步:在template 视图view 中使用,
    问题有:smithButton 命名,使用的时候则smith-button。
    请说下封装vue 组件的过程? vue 组件封装
    首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们
    传统项目开发:效率低、难维护、复用性等问题。
    然后,使用Vue.extend 方法创建一个组件,然后使用Vue.component 方法注册组件。子组件需
    要数据,可以在props 中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit
    方法。
  29. 建立组件的模板,先把架子搭起来,写写样式,考虑好组件的基本逻辑。
  30. 准备好组件的数据输入。即分析好逻辑,定好props 里面的数据、类型。
  31. 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。
  32. 封装完毕了,直接调用即可。
    vuex
    使用步骤:
    引入vuex
    1:下载vuex 模块
    2:新建一个store 文件夹(这个不是必须的),并在文件夹下新建store.js 文件,文件中引
    入我们的vue 和vuex
    3:引入之后用Vue.use 进行引用。
    注册全局
    在main.js 引入store,然后, 在实例化Vue 对象时加入store 对象:
    在组件中,就可以通过this. s t o r e 来 使 用 s t o r e 实 例 应 用 场 景 单 页 应 用 中 , 组 件 之 间 的 状 态 。 音 乐 播 放 、 登 录 状 态 、 加 入 购 物 车 理 解 : V u e x 是 一 个 专 为 V u e . j s 组 件 通 信 开 发 的 状 态 管 理 模 式 , 适 用 于 中 大 型 的 开 发 项 目 . 规 则 : 应 用 层 级 的 状 态 应 该 集 中 到 单 个 s t o r e 对 象 中 。 组 件 不 允 许 直 接 修 改 属 于 s t o r e 实 例 的 s t a t e 提 交 m u t a t i o n 是 更 改 状 态 的 唯 一 方 法 , 并 且 这 个 过 程 是 同 步 的 。 异 步 逻 辑 都 应 该 封 装 到 a c t i o n 里 面 。 g e t t e r s 可 以 对 S t a t e 进 行 计 算 操 作 , 它 就 是 S t o r e 的 计 算 属 性 , 可 以 复 用 ; 但 如 果 如 果 一 个 状 态 只 在 一 个 组 件 内 使 用 , 是 可 以 不 用 g e t t e r s v u e x 的 刷 新 数 据 丢 失 : 原 因 : s t o r e 里 的 数 据 是 保 存 在 运 行 内 存 中 的 , 当 页 面 刷 新 时 , 页 面 会 重 新 加 载 v u e 实 例 , s t o r e 里 面 的 数 据 就 会 被 重 新 赋 值 。 解 决 办 法 : 使 用 s t o r e . j s ( 数 据 存 储 插 件 ) , 存 储 数 据 到 本 地 浏 览 器 s t o r e . s e t 存 储 s t o r e . g e t 获 取 s t o r e . r e m o v e 删 除 措 施 : 1. l o c a l S t o r a g e 存 储 到 本 地 再 回 去 2. 重 新 获 取 接 口 获 取 数 据 属 性 有 五 种 , 分 别 是 S t a t e 、 G e t t e r 、 M u t a t i o n 、 A c t i o n 、 M o d u l e s t a t e 就 是 数 据 源 存 放 地 , g e t t e r s 可 以 对 S t a t e 进 行 计 算 操 作 , 是 S t o r e 的 计 算 属 性 S t a t e : 定 义 了 应 用 状 态 的 数 据 结 构 , 可 以 在 这 里 设 置 默 认 的 初 始 状 态 。 G e t t e r : 允 许 组 件 从 S t o r e 中 获 取 数 据 , m a p G e t t e r s 辅 助 函 数 仅 仅 是 将 s t o r e 中 的 g e t t e r 映 射 到 局 部 计 算 属 性 。 M u t a t i o n : 是 唯 一 更 改 s t o r e 中 状 态 的 方 法 , 且 必 须 是 同 步 函 数 。 A c t i o n : 用 于 提 交 m u t a t i o n , 而 不 是 直 接 变 更 状 态 , 可 以 包 含 任 意 异 步 操 作 。 M o d u l e : 允 许 将 单 一 的 S t o r e 拆 分 为 多 个 s t o r e 且 同 时 保 存 在 单 一 的 状 态 树 中 。 V u e x 中 a c t i o n s 和 m u t a t i o n s 的 区 别 ? M u t a t i o n s 的 更 改 是 同 步 更 改 , 用 于 用 户 执 行 直 接 数 据 更 改 , t h i s . store 来使用store 实例 应用场景 单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车 理解: Vuex 是一个专为Vue.js 组件通信开发的状态管理模式,适用于中大型的开发项目. 规则: 应用层级的状态应该集中到单个store 对象中。 组件不允许直接修改属于store 实例的state 提交mutation 是更改状态的唯一方法,并且这个过程是同步的。 异步逻辑都应该封装到action 里面。 getters 可以对State 进行计算操作,它就是Store 的计算属性,可以复用; 但如果如果一个状态只在一个组件内使用,是可以不用gettersvuex 的 刷新数据丢失: 原因: store 里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue 实例,store 里面的数据就会被重新赋值。 解决办法: 使用store.js(数据存储插件),存储数据到本地浏览器 store.set 存储store.get 获取store.remove 删除 措施:1.localStorage 存储到本地再回去2.重新获取接口获取数据 属性 有五种,分别是State、Getter、Mutation 、Action、Module state 就是数据源存放地,getters 可以对State 进行计算操作,是Store 的计算属性 State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。 Getter:允许组件从Store 中获取数据,mapGetters 辅助函数仅仅是将store 中的getter 映射到局部计算属性。 Mutation:是唯一更改store 中状态的方法,且必须是同步函数。 Action:用于提交mutation,而不是直接变更状态,可以包含任意异步操作。 Module:允许将单一的Store 拆分为多个store 且同时保存在单一的状态树中。 Vuex 中actions 和mutations 的区别? Mutations 的更改是同步更改,用于用户执行直接数据更改,this. store使storeVuexVue.js,.storestorestatemutationactiongettersStateStore,;使gettersvuexstore,vuestore使store.jsstore.setstore.getstore.remove1.localStorage2.StateGetterMutationActionModulestategettersStateStoreStateGetterStoremapGettersstoregetterMutationstoreActionmutationModuleStorestoreVuexactionsmutationsMutationsthis.store.commit(‘名’)触发。
    Actions 的更改是异步操作,用于需要与后端交互的数据更改,this.KaTeX parse error: Expected 'EOF', got '#' at position 680: …sh 模式url 里面永远带着#̲号,我们在开发当中默认使用这个…router.push(location) 来修改url,完成跳转
    路由传参的方法
  33. 字符串拼接: 路由后面直接拼接要传递的参数,用this.$route.params 接收。
  34. path 和query:path 后面跟要跳转的路由,query 后边跟要传递参数的对象用this.$route.query
    接收。
  35. name 和params : name 后面跟要跳转路由的名称, params 后面跟传递参数的对象, 用
    this. r o u t e . p a r a m s 接 收 。 v u e 路 由 的 钩 子 函 数 首 页 可 以 控 制 导 航 跳 转 , b e f o r e E a c h , a f t e r E a c h 等 , 一 般 用 于 页 面 t i t l e 的 修 改 。 一 些 需 要 登 录 才 能 调 整 页 面 的 重 定 向 功 能 。 b e f o r e E a c h 主 要 有 3 个 参 数 t o , f r o m , n e x t : t o : r o u t e 即 将 进 入 的 目 标 路 由 对 象 , f r o m : r o u t e 当 前 导 航 正 要 离 开 的 路 由 n e x t : f u n c t i o n 一 定 要 调 用 该 方 法 r e s o l v e 这 个 钩 子 。 执 行 效 果 依 赖 n e x t 方 法 的 调 用 参 数 。 可 以 控 制 网 页 的 跳 转 。 v u e − l o a d e r 是 什 么 ? 使 用 它 的 用 途 有 哪 些 ? 解 析 . v u e 文 件 的 一 个 加 载 器 , 跟 t e m p l a t e / j s / s t y l e 转 换 成 j s 模 块 。 用 途 : j s 可 以 写 e s 6 、 s t y l e 样 式 可 以 s c s s 或 l e s s 、 t e m p l a t e 可 以 加 j a d e 等 请 说 出 v u e . c l i 项 目 中 s r c 目 录 每 个 文 件 夹 和 文 件 的 用 法 ? a s s e t s 文 件 夹 是 放 静 态 资 源 ; c o m p o n e n t s 是 放 组 件 ; r o u t e r 是 定 义 路 由 相 关 的 配 置 ; v i e w 视 图 ; a p p . v u e 是 一 个 应 用 主 组 件 ; m a i n . j s 是 入 口 文 件 s c s s 是 什 么 ? 在 v u e . c l i 中 的 安 装 使 用 步 骤 是 ? 有 哪 几 大 特 性 ? v u e c l i 安 装 c s s 的 预 编 译 。 使 用 步 骤 : 第 一 步 : 用 n p m 下 三 个 l o a d e r ( s a s s − l o a d e r 、 c s s − l o a d e r 、 n o d e − s a s s ) 第 二 步 : 在 b u i l d 目 录 找 到 w e b p a c k . b a s e . c o n f i g . j s , 在 那 个 e x t e n d s 属 性 中 加 一 个 拓 展 . s c s s 第 三 步 : 还 是 在 同 一 个 文 件 , 配 置 一 个 m o d u l e 属 性 第 四 步 : 然 后 在 组 件 的 s t y l e 标 签 加 上 l a n g 属 性 , 例 如 : l a n g = ” s c s s ” 有 哪 几 大 特 性 : 1 、 可 以 用 变 量 , 例 如 ( route.params 接收。 vue 路由的钩子函数 首页可以控制导航跳转,beforeEach,afterEach 等,一般用于页面title 的修改。一些需要登录才 能调整页面的重定向功能。 beforeEach 主要有3 个参数to,from,next: to:route 即将进入的目标路由对象, from:route 当前导航正要离开的路由 next:function 一定要调用该方法resolve 这个钩子。执行效果依赖next 方法的调用参数。可以 控制网页的跳转。 vue-loader 是什么?使用它的用途有哪些? 解析.vue 文件的一个加载器,跟template/js/style 转换成js 模块。 用途:js 可以写es6、style 样式可以scss 或less、template 可以加jade 等 请说出vue.cli 项目中src 目录每个文件夹和文件的用法? assets 文件夹是放静态资源;components 是放组件;router 是定义路由相关的配置;view 视图; app.vue 是一个应用主组件;main.js 是入口文件 scss 是什么?在vue.cli 中的安装使用步骤是?有哪几大特性? vue cli 安装 css 的预编译。 使用步骤: 第一步:用npm 下三个loader(sass-loader、css-loader、node-sass) 第二步:在build 目录找到webpack.base.config.js,在那个extends 属性中加一个拓展.scss 第三步:还是在同一个文件,配置一个module 属性 第四步:然后在组件的style 标签加上lang 属性,例如:lang=”scss” 有哪几大特性: 1、可以用变量,例如( route.paramsvuebeforeEachafterEachtitlebeforeEach3tofromnexttoroutefromroutenextfunctionresolvenextvueloader使.vuetemplate/js/stylejsjses6stylescsslesstemplatejadevue.clisrcassetscomponentsrouter;viewapp.vuemain.jsscssvue.cli使vueclicss使npmloadersassloadercssloadernodesassbuildwebpack.base.config.jsextends.scssmodulestylelanglang=scss:1变量名称=值);2、可以用混合器,例如()3、可以嵌套
    Vue SSR
    服务端渲染
    Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出Vue 组件,进行生成
    DOM 和操作DOM。然而,也可以将同一个组件渲染为服务端的HTML 字符串,将它们直接发送到
    浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
    即:SSR 大致的意思就是vue 在客户端将标签渲染成的整个html 片段的工作在服务端完成,服务端
    形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。
    mint-ui 是什么?怎么使用?说出至少三个组件使用方法?
    基于vue 的前端组件库。
    npm 安装,然后import 样式和js,vue.use(mintUi)全局引入。在单个组件局部引入:import {Toast}
    from ‘mint-ui’。
    组件一:Toast(‘登录成功’);组件二:mint-header;组件三:mint-swiper
    V-model
    v-model 本质上是语法糖,其实就是既用v-bind:value 绑定了数据,又用v-on:input 添加了一个事
    件监听
    v-model 是什么?怎么使用? vue 中标签怎么绑定事件?
    可以实现双向绑定,
    指令(v-class、v-for、v-if、v-show、v-on)。vue 的model 层的data 属性。绑定事件: @click=doLog()/>
    iframe 的优缺点?
    iframe 也称作嵌入式框架,嵌入式框架和框架网页类似,它可以把一个网页的框架和内容嵌入在
    现有的网页中。
    优点:
    解决加载缓慢的第三方内容如图标和广告等的加载问题
    Security sandbox
    并行加载脚本
    方便制作导航栏
    缺点:
    iframe 会阻塞主页面的Onload 事件
    即时内容为空,加载也需要时间
    没有语意
    简述一下Sass、Less,且说明区别?
    他们是动态的样式语言,是CSS 预处理器,CSS 上的一种抽象层。他们是一种特殊的语法/语言
    而编译成CSS。变量符不一样,less 是@,而Sass 是 ; S a s s 支 持 条 件 语 句 , 可 以 使 用 i f e l s e , f o r 循 环 等 等 。 而 L e s s 不 支 持 ; S a s s 是 基 于 R u b y 的 , 是 在 服 务 端 处 理 的 , 而 L e s s 是 需 要 引 入 l e s s . j s 来 处 理 L e s s 代 码 输 出 C s s 到 浏 览 器 a x i o s 是 什 么 ? 怎 么 使 用 ? 描 述 使 用 它 实 现 登 录 功 能 的 流 程 ? 请 求 后 台 资 源 的 模 块 。 n p m i n s t a l l a x i o s − S 装 好 , 然 后 发 送 的 是 跨 域 , 需 在 配 置 文 件 中 c o n f i g / i n d e x . j s 进 行 设 置 。 后 台 如 果 是 T p 5 则 定 义 一 个 资 源 路 由 。 j s 中 使 用 i m p o r t 进 来 , 然 后 . g e t 或 . p o s t 。 返 回 在 . t h e n 函 数 中 如 果 成 功 , 失 败 则 是 在 . c a t c h 函 数 中 a x i o s + t p 5 进 阶 中 , 调 用 a x i o s . p o s t ( ‘ a p i / u s e r ’ ) 是 进 行 的 什 么 操 作 ? a x i o s . p u t ( ‘ a p i / u s e r / 8 ′ ) 呢 ? 跨 域 , 添 加 用 户 操 作 , 更 新 操 作 。 什 么 是 v u e 生 命 周 期 V u e 实 例 从 创 建 到 销 毁 的 过 程 , 就 是 生 命 周 期 。 从 开 始 创 建 、 初 始 化 数 据 、 编 译 模 板 、 挂 载 D o m → 渲 染 、 更 新 → 渲 染 、 销 毁 等 一 系 列 过 程 , 称 之 为 V u e 的 生 命 周 期 。 v u e 生 命 周 期 的 作 用 是 什 么 它 的 生 命 周 期 中 有 多 个 事 件 钩 子 , 让 我 们 在 控 制 整 个 V u e 实 例 的 过 程 时 更 容 易 形 成 好 的 逻 辑 生 命 周 期 初 始 化 阶 段 V u e 实 例 初 始 化 b e f o r e C r e a t e 可 以 在 这 加 个 l o a d i n g 事 件 , 在 加 载 实 例 时 触 发 V u e 实 例 , 初 始 化 完 成 , 开 始 渲 染 视 图 c r e a t e d 初 始 化 完 成 时 的 事 件 写 在 这 里 , 如 在 这 结 束 l o a d i n g 事 件 , 异 步 请 求 也 适 宜 在 这 里 调 用 开 始 处 理 模 板 b e f o r e M o u n t 模 板 渲 染 完 毕 m o u n t e d a j a x 传 入 数 据 阶 段 挂 载 元 素 , 获 取 到 D O M 节 点 数 据 更 新 阶 段 模 板 数 据 更 新 之 前 b e f o r e U p d a t e 模 板 数 据 更 新 之 后 u p d a t e d 如 果 对 数 据 统 一 处 理 , 在 这 里 写 上 相 应 函 数 销 毁 阶 段 组 件 销 毁 之 前 b e f o r e D e s t r o y 可 以 做 一 个 确 认 停 止 事 件 的 确 认 框 组 件 销 毁 之 后 d e s t r o y e d n e x t T i c k : 更 新 数 据 后 立 即 操 作 d o m 可 调 用 异 步 请 求 : c r e a t e d , b e f o r e M o u n t , m o u n t e d 因 为 在 这 三 个 钩 子 函 数 中 , d a t a 已 经 创 建 , 可 以 将 服 务 端 端 返 回 的 数 据 进 行 赋 值 。 但 是 本 人 推 荐 在 c r e a t e d 钩 子 函 数 中 调 用 异 步 请 求 , 因 为 在 c r e a t e d 钩 子 函 数 中 调 用 异 步 请 求 有 以 下 优 点 : 能 更 快 获 取 到 服 务 端 数 据 , 减 少 页 面 l o a d i n g 时 间 ; s s r 不 支 持 b e f o r e M o u n t 、 m o u n t e d 钩 子 函 数 , 所 以 放 在 c r e a t e d 中 有 助 于 一 致 性 N e x t t i c k 是 做 什 么 的 是 在 下 次 D O M 更 新 循 环 结 束 之 后 执 行 延 迟 回 调 , 再 修 改 数 据 之 后 使 用 ;Sass 支持条件语句,可以使用if{}else{},for{}循环 等等。而Less 不支持;Sass 是基于Ruby 的,是在服务端处理的,而Less 是需要引入less.js 来处理Less 代码输出Css 到浏览器 axios 是什么?怎么使用?描述使用它实现登录功能的流程? 请求后台资源的模块。npm install axios -S 装好,然后发送的是跨域,需在配置文件中 config/index.js 进行设置。后台如果是Tp5 则定义一个资源路由。js 中使用import 进来,然后.get 或.post。 返回在.then 函数中如果成功,失败则是在.catch 函数中 axios+tp5 进阶中,调用axios.post(‘api/user’)是进行的什么操作?axios.put(‘api/user/8′)呢?跨域, 添加用户操作,更新操作。 什么是vue 生命周期 Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom →渲染、更新→渲染、销毁等一系列过程,称之为Vue 的生命周期。 vue 生命周期的作用是什么 它的生命周期中有多个事件钩子,让我们在控制整个Vue 实例的过程时更容易形成好的逻辑 生命周期 初始化阶段 Vue 实例初始化_beforeCreate 可以在这加个loading 事件,在加载实例时触发Vue 实例,初始化完 成,开始渲染视图_created 初始化完成时的事件写在这里,如在这结束loading 事件,异步请求也 适宜在这里调用 开始处理模板_beforeMount 模板渲染完毕_mounted ajax 传入数据阶段挂载元素,获取到DOM 节点 数据更新阶段 模板数据更新之前beforeUpdate 模板数据更新之后updated 如果对数据统一处理,在这里写上相应函数 销毁阶段 组件销毁之前beforeDestroy 可以做一个确认停止事件的确认框 组件销毁之后destroyed nextTick : 更新数据后立即操作dom 可调用异步请求: created ,beforeMount,mounted 因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。但是本人推 荐在created 钩子函数中调用异步请求,因为在created 钩子函数中调用异步请求有以下优点: 能更快获取到服务端数据,减少页面loading 时间; ssr 不支持beforeMount 、mounted 钩子函数,所以放在created 中有助于一致性 Nexttick 是做什么的 是在下次DOM 更新循环结束之后执行延迟回调,再修改数据之后使用 ;Sass使ifelse,forLess;SassRubyLessless.jsLessCssaxios使使npminstallaxiosSconfig/index.jsTp5js使import.get.post.then.catchaxios+tp5axios.post(api/user)axios.put(api/user/8)vueVueDomVuevueVueVuebeforeCreateloadingVue,,createdloadingbeforeMountmountedajaxDOMbeforeUpdateupdatedbeforeDestroydestroyednextTick:domcreatedbeforeMountmounteddatacreatedcreatedloadingssrbeforeMountmountedcreatedNexttickDOM使nextTick ,则可以在回调
    中获取更新后的DOM
    swiper 插件从后台更新数据没有问题,css 代码也没问题,但图片不动。
    原因:swiper 提前初始化了,而这个时候数据还没有完全出来
    解决办法:nextTick ,用于解决dom 的先后执行问题
    Vue 中的ref(组件的参考)
    ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 r e f s 对 象 上 。 如 果 在 普 通 的 D O M 元 素 上 使 用 , 引 用 指 向 的 就 是 D O M 元 素 ; 如 果 用 在 子 组 件 上 , 引 用 就 指 向 组 件 实 例 : 应 用 场 景 1 : 指 向 添 加 r e f 的 d o m 元 素 比 如 在 e l e m e n t u i 中 表 单 验 证 就 是 这 样 的 机 制 应 用 场 景 2 : 父 组 件 通 过 r e f 获 取 子 组 件 来 进 行 操 作 v u e 的 实 例 属 性 refs 对象上。 如果在普通的DOM 元素上使用,引用指向的就是DOM 元素; 如果用在子组件上,引用就指向组件实例: 应用场景1: 指向添加ref 的dom 元素比如在element ui 中表单验证就是这样的机制 应用场景2:父组件通过ref 获取子组件来进行操作 vue 的实例属性 refsDOM使DOM1:refdomelementui2refvueel
    $el 用于获取vue 挂载的实例的dom 对象,在mounted 生命周期中才有效。
    第一次页面加载会触发哪几个钩子
    会触发beforeCreate, created, beforeMount, mounted
    DOM 渲染在哪个周期中就已经完成?
    DOM 渲染在mounted 中就已经完成了
    导航钩子有哪些?它们有哪些参数?
    导航钩子有: a/ 全局钩子和组件内独享的钩子。b/beforeRouteEnter 、afterEnter 、
    beforeRouterUpdate、beforeRouteLeave
    参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下
    一个路由,如果不用就拦截)最常用就这几种
    Computed watch 的区别
    1、功能上:computed 是计算属性,watch 是监听一个值的变化,然后执行对应的回调。
    2、是否调用缓存:computed 中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候
    会从缓存中读取,而watch 在每次监听的值发生变化的时候都会执行回调。
    3、是否调用return:computed 中的函数必须要用return 返回,watch 中的函数不是必须要用return。
    4、使用场景:
    computed:当一个属性受多个属性影响的时候,使用computed:购物车商品结算。
    watch----当一条数据影响多条数据的时候,使用watch-------搜索框。
    methods 方法
    1.是方法,主动调用
    2.每次需要重新加载
    3.无缓存性
    Computed 与methods 区别
    Computed:计算属性是基于他们的依赖进行缓存的,只有在他们的相关依赖发生改变时,才会
    重新求职;
    Methods:只要发生重新渲染,method 调用总会执行该函数。
    vue 如何实现按需加载配合webpack 设置
    webpack 中提供了require.ensure()来实现按需加载。
    vue 开发多语言项目
    采用i18n 来解决国际化问题,语言环境的存储时采用Cookie 的存储方法,通过路由实现不同模
    块加载不同的国际化配置文件
    https://www.cnblogs.com/rogerwu/p/7744476.html
    说说你对MVC 和MVVM 的理解
    Mvc
    angular 应用
    m 数据层
    v 视图层
    c 控制器逻辑层
    特点:把业务逻辑、模型数据、用户界面分离开来,让开发者将数据与表现解耦。
    MVC(Model View Controller 模型-视图-控制器)是一种Web 架构的模式。
    控制器(Contorller)修改数据(Model)视图改变(View)
    MVC 的实现了视图和模型的分离,避免了视图和模型糅合在一起,当视图改变的时候只要业
    务逻辑没变不需要改变模型;但是它有一个缺点缺点是因为MVC 中的控制器并不能直接更新视
    图,所以MVC 并不能实现视图和模型的完全分离,视图依然依赖模型的数据(数据结构)来显
    示,也就是说视图依赖模型。
    mvp
    M(model)负责数据层
    V(View)视图层
    P(presenter)是View 和Model 交互的桥梁。
    mvp 与其他两个模式最大的区别在数据层是视图层没有任何关系,完全依靠presenter,来控制逻
    辑,与中转
    MVP 用展示器代替了控制器,而展示器是可以直接更新视图,所以MVP 中展示器可以处理
    视图的请求并递送到模型又可以根据模型的变化更新视图,实现了视图和模型的完全分离。
    MVVM
    Vue 基于mvvm
    View 和Model 之间并没有直接的联系,而是通过ViewMode(监听器)l 进行交互
    MVVM 用视图模型代替了MVP 中的展示器,视图模型和视图实现了双向绑定,当视图发生变
    化的时候视图模型也会发生改变,当视图模型变化的时候视图也随之变化。
    ##Model 代表数据模型,也可以在Model 中定义数据修改和操作的业务逻辑。
    View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
    ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步
    View 和Model 的对象,连接Model 和View。
    在MVVM 架构下,View 和Model 之间并没有直接的联系,而是通过ViewModel 进行交互,
    Model 和ViewModel 之间的交互是双向的,因此View 数据的变化会同步到Model 中,而Model
    数据的变化也会立即反应到View 上。
    ViewModel 通过双向数据绑定把View 层和Model 层连接了起来,而View 和Model 之间
    的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM,
    不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM 来统一管理。
    mvvm 框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?
    一个model+view+viewModel 框架,数据模型model,viewModel 连接两个
    区别:vue 数据驱动,通过数据来显示视图层而不是节点操作。
    场景:数据操作比较多的场景,更加便捷
    vue 中name 的作用
    1:当项目使用keep-alive 时,可搭配组件name 进行缓存过滤
    2:使用递归组件需要用到它
    3:打开浏览器页面的vue 工具,name 是什么名字,显示的就是什么了
    template 编译
    简而言之,就是先转化成AST 树,再得到的render 函数返回VNode(Vue 的虚拟DOM 节点)
    详情步骤:
    首先,通过compile 编译器把template 编译成AST 语法树(abstract syntax tree 即源代码的抽象
    语法结构的树状表现形式),compile 是createCompiler 的返回值,createCompiler 是用以创建编译器
    的。另外compile 还负责合并option。
    然后,AST 会经过generate(将AST 语法树转化成render funtion 字符串的过程)得到render 函
    数,render 的返回值是VNode,VNode 是Vue 的虚拟DOM 节点,里面有(标签名、子节点、文本等
    等)
    v-for 中:key key 作用
    key 是为了给Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,需
    要为每项提供一个唯一的key 属性。即:key 的作用主要是为了高效的更新虚拟DOM,
    key 是给每一个vnode(虚拟节点)的唯一id,可以依靠key,更准确, 更快的拿到oldVnode 中对
    应的vnode 节点。
  36. 更准确
    因为带key 就不是就地复用了,在sameNode 函数a.key === b.key 对比中可以避免就地复用
    的情况。所以会更加准确。
  37. 更快
    利用key 的唯一性生成map 对象来获取对应节点,比遍历方式更快。
    用index 做key 值:
    在最后一条数据后再加一条数据,旧数据直接复用之前的,新渲染最后一条数据用index 作为key,
    没有任何问题,在中间插入一条数据,新增数据之前的直接复用,新增数据及其之后的重新渲染,影
    响性能
    vue 中key 值的作用
    当Vue.js 用v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据
    项的顺序被改变,Vue 将不会移动DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并
    且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟DOM
    v-if 和v-for 不能共用:
    v-for 比v-if 具有更高的优先级,这意味着v-if 将分别重复运行于每个v-for 循环中。通过
    v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会
    在v-if 为否的时候运算v-for。
    vue 只中接口管理
    在request.js 中对axios 请求和响应进行劫持,统一处理,然后在api 文件夹中引入request.js
    后再使用封装后的方法进行请求
    vue 阻止冒泡
    js 冒泡概念:当父元素内多级子元素绑定了同一个事件,js 会依次从内往外或者从外往内(?)
    执行每个元素的该事件,从而引发冒泡
    js 解决冒泡:event.stopPropagation()
    vue 解决冒泡: 事件.stop,例如:@click.stop="" ,@mouseover.stop=""
    vue 中组件调用
    子组件调用父组件的方法:
    1:直接在子组件中通过this. p a r e n t . e v e n t 来 调 用 父 组 件 的 方 法 2 : 在 子 组 件 里 用 parent.event 来调用父组件的方法 2:在子组件里用 parent.event2emit 向父组件触发一个事件,父组件监听这个事件就行了
    3:父组件把方法传入子组件中,在子组件里直接调用这个方法
    父组件调用子组件的方法
    使用 r e f s 组 件 之 间 的 传 值 v u e 组 件 传 值 v u e 组 件 通 信 父 组 件 与 子 组 件 传 值 : 父 组 件 通 过 标 签 上 面 定 义 传 值 , 子 组 件 通 过 p r o p s 方 法 接 受 数 据 子 组 件 向 父 组 件 传 递 数 据 , 子 组 件 通 过 refs 组件之间的传值vue 组件传值vue 组件通信 父组件与子组件传值:父组件通过标签上面定义传值,子组件通过props 方法接受数据 子组件向父组件传递数据,子组件通过 refsvuevue:,props,emit 方法传递参数
    非父子组件间的数据传递,兄弟组件传值:eventBus,
    就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比
    较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求
    咯。技术只是手段,目的达到才是王道。)
    通过vuex 来通信
    父组件监听子组件的生命周期:
    在父组件引用子组件时通过@hook 来监听
    Vue 的父组件和子组件生命周期钩子函数执行顺序?
    Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下4 部分:
    加载渲染过程:
    父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子
    beforeMount -> 子mounted -> 父mounted
    子组件更新过程
    父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
    父组件更新过程
    父beforeUpdate -> 父updated
    销毁过程
    父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
    props 与state 的区别?
    props:一般用于父组件向子组件通信,在组件之间通信使用。
    state:一般用于组件内部的状态维护,更新组建内部的数据,状态,更新子组件的props 等。
    Vue 怎么用vm. s e t ( ) 解 决 对 象 新 增 属 性 不 能 响 应 的 问 题 ? V m . set() 解决对象新增属性不能响应的问题? Vm. set()Vm.set()原理
    如果目标是数组,直接使用数组的splice 方法触发相应式;
    如果目标是对象,会先判读属性是否存在、对象是否是响应式,最终如果要对属性进行响应式
    处理,则是通过调用defineReactive 方法进行响应式处理( defineReactive 方法就是Vue 在初始
    化对象时,给对象属性采用Object.defineProperty 动态添加getter 和setter 的功能所调用的方法)
    vue 路由钩子函数
    首页可以控制导航跳转,beforeEach,afterEach 等,一般用于页面title 的修改。一些需要
    登录才能调整页面的重定向功能。
    beforeEach 主要有3 个参数to,from,next:
    to:route 即将进入的目标路由对象,
    from:route 当前导航正要离开的路由
    next:function 一定要调用该方法resolve 这个钩子。执行效果依赖next 方法的调用
    参数。可以控制网页的跳转。
    数据双向绑定原理
    通过Object.defineProperty() 对数据进行劫持,
    1.采用数据劫持结合发布—订阅模式的方式,
    2.通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布
    消息给订阅者,触发相应监听回调。
    监听数据原理:
    Object . defineproperty
    get
    读取对象
    set
    设置对象
    只能监听一层监听
    get
    读取对象
    set
    设置对象
    只能监听一层监听
    Vue 框架怎么实现对象和数组的监听
    Vue 框架是通过遍历数组和递归遍历对象,从而达到利用Object.defineProperty() 也能
    对对象和数组(部分方法的操作)进行监听。
    对keep-alive 的了解
    keep-alive 是Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
    在vue 2.1.0 版本之后,keep-alive 新加入了两个属性: include(包含的组件缓存) 与exclude(排
    除的组件不缓存,优先级大于include)
    keep-alive 生命周期
    activated 和deactivated
    keep-alive 的生命周期
    1.activated: 页面第一次进入的时候,钩子触发的顺序是created->mounted->activated
    2.deactivated: 页面退出的时候会触发deactivated,当再次前进或者后退的时候只触发activated
    Vue todo 思路
    结构: 输入部分( input )和输出部分( ul )
    逻辑:用户输入之后,通过事件触发拿到用户输入的数据存起来,
    将用户数据集合通过v-for 渲染到页面上
    当用户点击清单项,通过事件触发移出对应事件
    Vue 重置data
    使用Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象
    this. d a t a 获 取 当 前 状 态 下 的 d a t a t h i s . data 获取当前状态下的data this. datadatathis.options.data()获取该组件初始状态下的data。
    bject.assign(this. d a t a , t h i s . data, this. data,this.options.data())
    a t t r s 和 attrs 和 attrslisteners 的使用场景
    组件传值,祖孙组件有跨度的传值。
    组件传值的时候会用到爷爷在父亲组件传递值,父亲组件会通过 a t t r s 获 取 到 不 在 父 亲 p r o p s 里 面 的 所 有 属 性 , 父 亲 组 件 通 过 在 孙 子 组 件 上 绑 定 attrs 获取到不在父亲props 里面的所有属性,父亲组件通过在孙子组件上绑定 attrspropsattrs 和 l i s t e n e r s 使 孙 组 件 获 取 爷 爷 传 递 的 值 并 且 可 以 调 用 在 爷 爷 那 里 定 义 的 方 法 组 件 访 问 子 组 件 的 实 例 或 者 子 元 素 : 通 过 t h i s . listeners 使孙组件获取爷爷传递的 值并且可以调用在爷爷那里定义的方法 组件访问 子组件的实例或者子元素:通过this. listeners使访this.refs
    子组件中访问到父组件的实例:通过this. p a r e n t 组 件 中 访 问 到 根 实 例 : 通 过 t h i s . parent 组件中访问到根实例:通过this. parent访this.root
    Vue is
    动态组件,当你多个组件需要通过v-if 切换时,可以使用is 来简化代码
    vue 中is 的属性引入是为了解决dom 结构中对放入html 的元素有限制的问题
    Slot
    slot, 插槽, 在使用组件的时候, 在组建内部插入东西.
    组件封装的时候最常使用到
    单个插槽、具名插槽和作用域插槽三种
    单个插槽可以放置在组件的任意位置,但是就像它的名字一样,一个组件中只能有一个该类插
    槽。相对应的,具名插槽就可以有很多个,只要名字(name 属性)不同就可以了。
    具名插槽
    插槽加了name 属性,就变成了具名插槽。具名插槽可以在一个组件中出现N 次,出现在不同的
    位置。
    当出现多个需要分发的内容时,可以为插槽命名,并在子组件中根据不同的名称进行分开管理
    使用来指定我是插槽的内容
    Vue mixin
    为组件定义可复用的方法,可以在mixin 对象里定义组件的任何属性,在组件使用mixin 时,mixin
    中的属性会添加到组件属性中
    混入(mixin) 提供了一种非常灵活的方式,来分发Vue 组件中的可复用功能,Vue.mixin 给我
    们提供了一种混入Vue 实例的方法,创建了混入对象之后,我们自定义的方法或者变量可以很轻松
    的挂载在Vue 实例上,它分为局部混入和全局混入
    局部混入就是部分混入,也就是只有引入了mixin 的混入对象才可以使用,并且只有在引入了
    mixin 混入对象的组件中才生效;
    全局混入我们只需要把mixin.js 引入到main.js 中,然后将mixin 放入到Vue.mixin()方法中
    即可;
    mixin 混入对象和Vuex 的区别:
    Vuex 是状态共享管理,所以Vuex 中的所有变量和方法都是可以读取和更改并相互影响的;
    mixin 可以定义公用的变量或方法,但是mixin 中的数据是不共享的,也就是每个组件中的mixin 实
    例都是不一样的,都是单独存在的个体,不存在相互影响的;
    mixin 混入对象值为函数的同名函数选项将会进行递归合并为数组,两个函数都会执行,只不过先执
    行mixin 中的同名函数;
    mixin 混入对象值为对象的同名对象将会进行替换,都优先执行组件内的同名对象,也就是组件内的
    同名对象将mixin 混入对象的同名对象进行覆盖;
    Vue 首页优化
    异步路由和异步加载
    还有分屏加载, 按需加载, 延时加载图片等, cdn, 域名才分
    Vue 定时器销毁
    通过$once 来监听定时器,在beforeDestroy 钩子可以被清除。
    v-if 和v-show 区别
    v-if 按照条件是否渲染,v-show 是display 的block 或none
    v-if 不渲染DOM,是DOM 销毁和重建,v-show 会渲染DOM,是css 的display 显示和隐藏
    v-show 使用场景:
    预渲染需求
    需要频繁切换显示状态
    自定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?
    全局定义指令:在vue 对象的directive 方法里面有两个参数,一个是指令名称,另外一个是
    函数。组件内定义指令:directives
    钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更
    新)
    钩子函数参数:el、binding
    说出至少4 种vue 当中的指令和它的用法?
    v-if:判断是否渲染组件;v-for:数据循环出来;v-bind:class:绑定一个属性;v-model:
    实现双向绑定
    r o u t e 和 route 和 routerouter 的区别
    r o u t e 是 “ 路 由 信 息 对 象 ” , 包 括 p a t h , p a r a m s , h a s h , q u e r y , f u l l P a t h , m a t c h e d , n a m e 等 路 由 信 息 参 数 。 而 route 是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name 等路由信息参数。而 routepathparamshashqueryfullPathmatchednamerouter 是“路由实例”对象包括了路由的跳转方法,钩子函数等
    vue 常用的修饰符
    .prevent: 提交事件不再重载页面;
    .stop: 阻止单击事件冒泡;
    .self: 当事件发生在该元素本身而不是子元素的时候会触发;
    .capture: 事件侦听,事件发生的时候会调用
    什么是vue 计算属性
    在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次
    使用的情况下,尽量采取计算属性的方式。
    好处:
  38. 使得数据处理结构清晰;
  39. 依赖于数据,数据更新,处理结果自动更新;
  40. 计算属性内部this 指向vm 实例;
  41. 在template 调用时,直接写计算属性名即可;
  42. 常用的是getter 方法,获取数据,也可以使用set 方法改变数据;
  43. 相较于methods,不管依赖的数据变不变,methods 都会重新计算,但是依赖数据不变
    的时候computed 从缓存中获取,不会重新计算
    在使用计算属性的时,函数名和data 数据源中的数据可以同名吗
    不能同名,会报错, 因为不管是计算属性还是data 还是props 都会被挂载在vm 实例上,因
    此这三个都不能同名
    vue 打包后静态资源图片失效的问题
    设置assetsPublicPath 将assetsPublicPath: ‘/’ 改为assetsPublicPath: ‘./’
    vue 动态设置img 的src 不生效的问题
    因为动态添加src 被当做静态资源处理了,没有进行编译,所以要加上require。
    vue 单页面应用及其优缺点
    Vue 的目标是通过尽可能简单的API 实现响应的数据绑定和组合的视图组件,核心是一个响
    应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
    vue 单向数据流
    父级prop 的更新会向下流动到子组件中,每次父级组件发生更新时,子组件中所有的prop 都
    将会刷新为最新的值
    直接给一个数组项赋值vue 能检测到变化吗? 检测变化
    不能,解决办法
    利用索引直接设置一个数组的项时:vue.set;vm.$set(vue.set 别名);Arry.Prototype.splice
    修改数组的长度:vm.items.splice
    vue 性能优化:
    vue 应用运行时性能优化措施, 引入生产环境的Vue 文件, 使用单文件组件预编译模板
    提取组件的CSS 到单独到文件, 利用Object.freeze()提升性能, 扁平化Store 数据结构
    合理使用持久化Store 数据, 组件懒加载, Vue 应用加载性能优化措施
    服务端渲染/ 预渲染, 减少http 请求,合理设置HTTP 缓存
    使用浏览器缓存, 启用压缩
    CSS Sprites, LazyLoad Images , 尽量避免使用eval 和Function
    Vue jquery 区别: vue 区别
    Jquery 专注于视图层,通过DOM 操作去实现页面的一些逻辑渲染;vue 专注于数据层,通过数
    据的双向绑定,最终表现在DOM 层面,减少了DOM 操作。
    VUE 使用了组件化的思想,提高开发效率,方便重复利用,便于协同开发。
    Vue angular 以及react 的区别(待完善)
    1.与AngularJS 的区别
    相同点:
    都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支
    持双向数据绑定;都不支持低端浏览器。
    不同点:
    AngularJS 的学习成本高,比如增加了Dependency Injection 特性,而Vue.js 本身提供的
    API 都比较简单、直观;在性能上,AngularJS 依赖对数据做脏检查,所以Watcher 越多越慢;Vue.js
    使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。
    2.与React 的区别
    相同点:
    React 采用特殊的JSX 语法,Vue.js 在组件开发中也推崇编写.vue 特殊文件格式,对文件
    内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌
    套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;都不内置列数AJAX,Route 等功
    能到核心包,而是以插件的方式加载;在组件开发中都支持mixins 的特性。
    不同点:
    React 采用的Virtual DOM 会对渲染出来的结果做脏检查;Vue.js 在模板中提供了指令,
    过滤器等,可以非常方便,快捷地操作Virtual DOM。
    相同点:
    1.都支持服务器端渲染
    2.都有Virtual DOM,组件化开发,通过props 参数进行父子组件数据的传递,都实现
    webComponent 规范
    3.数据驱动视图
    4.都有支持native 的方案,React 的React native,Vue 的weex
    5.都有管理状态,React 有redux,Vue 有自己的Vuex(自适应vue,量身定做)
    不同点:
    1.React 严格上只针对MVC 的view 层,Vue 则是MVVM 模
    2.virtual DOM 不一样,vue 会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.
    而对于React 而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react 中会需要
    shouldComponentUpdate 这个生命周期函数方法来进行控制
    3.组件写法不一样, React 推荐的做法是JSX + inline style, 也就是把HTML 和CSS
    全都写进JavaScript 了,即’all in js’;
    Vue 推荐的做法是webpack+vue-loader 的单文件组件格式,即html,css,jd 写在同
    一个文件;
    4.数据绑定: vue 实现了数据的双向绑定,react 数据流动是单向的
    5.state 对象在react 应用中不可变的,需要使用setState 方法更新状态;
    在vue 中,state 对象不是必须的,数据由data 属性在vue 对象中管理;
    Vue react angular 选择: vue 选择
    考虑当前团队成员技术栈, 基本遵循少数服从多数的情况
    考虑人员招聘成本, 我上家公司当初希望切换到react 框架, 结果招聘非常难, 新人迟迟进
    不来影响开发进度
    业务场景考虑, 在平台类应用,并且未来将长期持续维护, 团队开发人员经验不足的情况下,
    选择angular 是不错的方案
    架构上倾向设计的视图层更轻, 尽量弱化框架的绑定
    首先会根据团队的技术栈来进行选型,有利于团队管理及技术交流,在此基础上不断演化出适
    合公司内部的实现方式;
    抛开团队来说的话,个人会选择vue,原因是:
    一直接触的都是vue,目前没有什么痛感,喜欢使用模板
    轻量、语法简单,支持模板和渲染函数的弹性选择
    更快的渲染+更小的体积
    vue 的优势:轻量级框架、简单易学、双向数据绑定、组件化、视图、数据和结构的分离、虚拟
    DOM、运行速度快
    懒加载的实现原理
    意义:懒加载的主要目的是作为服务器前端的优化。减少请求数或延迟加载请求数
    原理:先加载一部分数据,当触发某个条件是利用异步加载剩余的数据,新得到的数据不会影响。
    原来数据显示,同时最大程度减少服务器端的资源耗用。
    实现方式:
    1.第一种是纯粹的延迟加载,使用setTimeOut 或setTnterval 进行加载延迟。
    2.第二种是条件加载,符合某些条件,或触发了某些事件才开始异步加载。
    3.可视区加载,即加载用户可看到的区域,这个主要有监控滚动条来实现,一
    般会在距看到某图片前一定距离便开始加载,这样能保证用户拉下时正好看到。
    后端接口不同,url 不同
    devServer 中把所有的服务人员的地址代理都写进去,
    然后动态更改接口的baseUrl,这样切换不同后端人员的时候不用重启
    Vue 项目中遇到的问题: 项目问题
    1:在写项目的时候偶然遇到了一个问题,在进入一个城市选择页面时,城市列表总是需要一秒
    后才能加载出来,出现了页面抖动,数据加载太多导致页面抖动用beforeRouteEnter(路由钩子)解
    决在路由跳转前加载数据,
    2:从详情页返回列表页时, 要保存所有状态, 比如: 滚动条位置, 数据, 下拉数据等
    当时想用keep-alive, 后来没用, 直接存储一些关键数据, 返回到router 时重新加载了数据
    Vue 项目优化
    (1)代码层面的优化
    v-if 和v-show 区分使用场景
    computed 和watch 区分使用场景
    v-for 遍历必须为item 添加key,且避免同时使用v-if
    长列表性能优化
    事件的销毁
    图片资源懒加载
    路由懒加载
    第三方插件的按需引入
    优化无限列表性能
    服务端渲染SSR or 预渲染
    (2)Webpack 层面的优化
    Webpack 对图片进行压缩
    减少ES6 转为ES5 的冗余代码
    提取公共代码
    模板预编译
    提取组件的CSS
    优化SourceMap
    构建结果输出分析
    Vue 项目的编译优化
    (3)基础的Web 技术的优化
    开启gzip 压缩
    浏览器缓存
    CDN 的使用
    使用Chrome Performance 查找性能瓶颈
    登录流程:
    当我点击登录的时候,我先判断我输入的值是否符合规则,如果符合,就把参数拼接到接口上,
    然后请求,后台会返回一个token 值,我把token 放在本地存储中,在全局路由守卫中,当我要访问
    一个需要登录才可以进入的路由的时候,我就判断本地存储中有没有这个token 值,如果有,就进入
    这个路由,如果没有,就返回登录页面登录。
    Loading 动画怎么实现:
    用axios 拦截器实现loading 动画效果首先新建一个loading 组件,里面写一些动画效果,
    然后在vuex 里面写一个状态来控制我的loading 动画组件的显示隐藏,然后在全局main.js 中配置axios
    拦截器,分别定义一个请求拦截器和响应拦截器,在请求数据时执行请求拦截器,改变我vuex 里面
    定义的状态,让loading 动画显示,反之,数据请求到之后,隐藏loading 动画即可。
    图片懒加载怎么实现
    我们先不给设置src,把图片真正的URL 放在另一个属性data-src 中,在需要的时候也就是
    图片进入可视区域的之前,将URL 取出放到src 中。
    React
    React
    React 是Facebook 开发的前端JavaScript 库
    V 层:react 并不是完整的MVC 框架,而是MVC 中的C 层
    虚拟DOM:react 引入虚拟DOM,每当数据变化通过reactdiff 运算,将上一次的虚拟DOM 与本
    次渲染的DOM 进行对比,仅仅只渲染更新的,有效减少了DOM 操作
    JSX 语法:js+xml,是js 的语法扩展,编译后转换成普通的js 对象
    组件化思想:将具有独立功能的UI 模块封装为一个组件,而小的组件又可以通过不同的组合嵌
    套组成大的组件,最终完成整个项目的构建
    单向数据流:指数据的流向只能由父级组件通过props 讲数据传递给子组件,不能由子组件向父
    组件传递数据
    要想实现数据的双向绑定只能由子组件接收父组件props 传过来的方法去改变父组件数据,而不
    是直接将子组件数据传给父组件
    生命周期:简单说一下生命周期:Mounting(挂载)、Updateing(更新)、Unmounting(卸载)
    概念:
    Store:保存数据的地方,你可以把它看成一个容器,整个应用只能有一个Store。
    State:Store 对象包含所有数据,如果想得到某个时点的数据,就要对Store 生成快照,这种时
    点的数据集合,就叫做State。
    Action:State 的变化,会导致View 的变化。但是,用户接触不到State,只能接触到View。所以,
    State 的变化必须是View 导致的。Action 就是View 发出的通知,表示State 应该要发生变化了。
    Action Creator:View 要发送多少种消息,就会有多少种Action。如果都手写,会很麻烦,所以我
    们定义一个函数来生成Action,这个函数就叫Action Creator。
    Reducer:Store 收到Action 以后,必须给出一个新的State,这样View 才会发生变化。这种State
    的计算过程就叫做Reducer。Reducer 是一个函数,它接受Action 和当前State 作为参数,返回一个新
    的State。
    dispatch:是View 发出Action 的唯一方法。
    React 优点
    简洁,没有过多Api,一个单花括号搞定一切
    JSX − JSX 是JavaScript 语法的扩展。React 开发不一定使用JSX ,但我们建议使用它。
    组件− 通过React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的
    开发中。
    单向响应的数据流− React 实现了单向响应的数据流,从而减少了重复代码,这也是它
    为什么比传统数据绑定更简单
    为什么React 官方推荐不能直接去修改状态(state)
    因为进行内存比较,永远要比deepWatch 效率要高
    react 新特性:
    新的生命周期
    新的语法
    优化
    hooks
    1:Fragment
    不会被渲染的包裹组件
    2:Context
    定义:Context 提供了一种方式,能够让数据在组件树中传递而不必一级一级手动传递。
    createContext
    父子组件可以通过props 自顶向下的传递数据
    当组件深度嵌套时,从顶层组件向最内层组件传递数据就不那么方便
    因为在老的Context 中由上而下的“触发链”有可能被shouldComponentUpdate 打断。
    3:新生命周期确保渲染完成之前不做任何会引发重新渲染的操作
    React 新增钩子函数
    最新的生命周期删掉了三个will 方法,新增了两个get 方法:
    delete: componentWillMount, componentWillReceiveProps, componentWillUpdate,
    原来(React v16.0 前)的生命周期在React v16 推出的Fiber 之后就不合适了,因为如果
    要开启async rendering,在render 函数之前的所有函数,都有可能被执行多次。
    第二三个这两个生命周期都在reconciliation 过程中
    在异步模式下,reconciliation 会被打断,所以可能触发多次
    如果在这两个生命周期做一些fetch 请求、props 的回调等产生副作用的事情,那么可能
    会导致执行多次
    add: static getDerivedStateFromProps,
    用于替换componentWillReceiveProps,可以用来控制props 更新state 的过程;
    它返回一个对象表示新的state;如果不需要更新,返回null 即可
    getSnapshotBeforeUpdate(
    用于替换componentWillUpdate,该函数会在update 后DOM 更新前被调用,
    用于读取最新的DOM 数据,返回值将作为componentDidUpdate 的第三个参数
    5:HOOK
    hook 特性可以它让你在不编写class 的情况下使用state 以及其他的React 特性。它是一个特殊的
    函数
    Hooks
    React Hooks 初始化组件的一种方式,它们是一些(Hook)钩子函数
    最重要的三个Hooks useState,useEffect,useContext
    1:useState:让函数变成了一个有状态的函数。
    2:useEffect Hook 可以视作componentDidMount 、componentDidUpdate 和
    componentWillUnmount 的组合体。
    可以有多个
    依赖数组依赖的值最好不要超过3 个
    3:useContext 提供了上下文(context)的功能
    render 函数是发生在哪个生命周期
    正确答案应该是在willMount 和didMount 之间
    调用render 时,DOM 一定会更新吗,为什么
    不一定更新
    React 组件中存在两类DOM,render 函数被调用后, React 会根据props 或者state 重新创建一
    棵virtual DOM 树,虽然每一次调用都重新创建,但因为创建是发生在内存中,所以很快不影响性能。
    而virtual dom 的更新并不意味着真实DOM 的更新,React 采用diff 算法将virtual DOM 和真实DOM
    进行比较,找出需要更新的最小的部分,这时Real DOM 才可能发生修改
    所以每次state 的更改都会使得render 函数被调用,但是页面DOM 不一定发生修改
    React 生命周期
    React 生命周期分三个阶段初始化阶段数据更新阶段销毁阶段
    初始化阶段

Constructor -》componentWillMount-》render》componentDidMount

父组件状态更新,所有的子组件render 全部执行
父组件的componentDidMount 会在所有子组件全局加载完毕最后执行

getDefaultProps:获取实例的默认属性

getInitialState:获取每个实例的初始化状态
constructor :声明State 变量
componentWillMount:组件即将被装载、渲染到页面上
render:组件在这里生成虚拟的DOM 节点
componentDidMount:组件真正在被装载之后
数据更新阶段

ComponentWillReceiveProps(props) 传入props 发生改变时执行,并获取更新之后props

shouldComponentUpdate(props) 里面返回一个布尔值控制是否执行更新流程,在组件传props
可以获取修改之后的props
this.prosp 修改之前的props 参数获取修改之后的值
shouldComponentUpdate 与React.PureComponent 不能共用React.PureComponent 会自动执行
一次浅比较
componentWillUpdate 更新之前
render
componentDidUpdate 更新之后

componentWillReceiveProps:组件将要接收到属性的时候调用

shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更
新,阻止
render 调用,后面的函数不会被继续执行了)
componentWillUpdate:组件即将更新不能修改属性和状态render:组件重新描绘
componentDidUpdate:组件已经更新三
组件销毁阶段
componentWillUnmount 组件即将销毁
初始化:初始进入页面→ constructor → componentWillMount → render → componentDidMount →
componentWillUnmount;
更新:setState → componentWillReceiveProps → shouldComponentUpdate → componentWillUpdate →
render → componentDidUpdate → componentWillUnmount。
shouldComponentUpdate 是做什么的,(react 性能优化是哪个周期函数?)
shouldComponentUpdate 这个方法用来判断是否需要调用render 方法重新绘制dom
因为DOM 的描绘非常消耗性能,如果我们能在shouldComponentUpdate 方法中能够写出更优化
的dom diff 算法,可以极大的提高性能
数据为什么一定要在DidMount 里获取更新
componentDidMount 方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以
保证数据的加载
React 的生命周期函数中,当props 改变时会引发的后续变化,rander()函数什么时候执行
componentWillUpdate(){}之后
render
componentDidupdate(){}之前
react diff 原理(常考,大厂必考)
把树形结构按照层级分解,只比较同级元素。
给列表结构的每个单元添加唯一的key 属性,方便比较。
React 只会匹配相同class 的component(这里面的class 指的是组件的名字)
合并操作,调用component 的setState 方法的时候, React 将其标记为dirty.到每一个事件循环结束,
React 检查所有标记dirty 的component 重新绘制.
选择性子树渲染。开发人员可以重写shouldComponentUpdate 提高diff 的性能。
React 组件通信react 组件传值
父组件通过props 传递数据给子组件,子组件通过调用父组件传来的函数传递数据给父组件,
兄弟组件通信通过共同的父组件来管理状态和事件函数。
跨多层次组件通信使用Context
.任意组件:Redux 或者Event Bus
父组件向子组件通信: props
子组件向父组件通信: 回调函数/自定义事件
跨级组件通信: 层层组件传递props/context
没有嵌套关系组件之间的通信: 自定义事件安装events 包
在进行组件通信的时候,主要看业务的具体需求,选择最合适的;
当业务逻辑复杂到一定程度,就可以考虑引入Mobx,Redux 等状态管理工具
React 如何进行组件/逻辑复用?
高阶组件:
属性代理
反向继承
渲染属性
react-hooks
Mixin:弃用
受控组件
在HTML 中,类似, 和 这样的表单元素会维护自身的状态,并基
于用户的输入来更新,当用户提交表单时,前面提到的元素的值将随表单一起被发送,但在React 中
会有些不同,包含表单元素的组件将会在state 中追踪输入的值,并且每次调用回调函数时如
onChange 会更新state,重新渲染组件,一个输入表单元素,它的值通过React 的这种方式来控制,
这样的元素就被称为”受控元素”
Hoc(高阶组件)
高阶组件和高阶函数就是同一个东西。我们实现一个函数,传入一个组件,然后在函数内部再实
现一个函数去扩展传入的组件,最后返回一个新的组件,这就是高阶组件的概念,作用就是为了更好
的复用代码。
特点:
高阶组件(HOC)应该是无副作用的纯函数,且不应该修改原组件,即原组件不能有变动
高阶组件(HOC)不关心你传递的数据(props)是什么,并且新生成组件不关心数据来源
高阶组件(HOC)接收到的props 应该透传给被包装组件即直接将原组件prop 传给包装组件
高阶组件完全可以添加、删除、修改props
React 中的状态是什么?它是如何使用的?
状态是React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现和行
为的对象。与props 不同,它们是可变的,并创建动态和交互式组件。可以通过this.state() 访问它

解释React 中render() 的目的
每个React 组件强制要求必须有一个render()。它返回一个React 元素,是原生DOM 组件的表
示,如果需要渲染多个HTML 元素,则必须将它们组合在一个封闭标记内,例如、、

等,此函数必须保持纯净,即必须每次调用时都返回相同的结果 在React 中,一切都是组件 组件是React 应用UI 的构建块。这些组件将整个UI 分成小的独立并可重用的部分 每个组件彼此独立,而不会影响UI 的其余部分 无状态组件,与有状态组件的区别 无状态组件主要用来定义模板,接收来自父组件props 传递过来的数据,使用{props.xxx}的表达 式把props 塞到模板里面 有状态组件主要用来定义交互逻辑和业务数据,使用{this.state.xxx}的表达式把业务数据挂载到容 器组件的实例上(有状态组件也可以叫做容器组件,无状态组件也可以叫做展示组件),然后传递 props 到展示组件,展示组件接收到props,把props 塞到模板里面 在哪些生命周期中可以修改组件的state componentDidMount 和componentDidUpdate constructor、componentWillMount 中setState 会发生错误:setState 只能在mounted 或mounting 组件中执行 componentWillUpdate 中setState 会导致死循环 React Fiber 种基于浏览器的单线程调度算法.一种将recocilation (递归diff),拆分成无数个小任务的算法; 它随时能够停止,恢复。停止恢复的时机取决于当前的一帧(16ms)内,还有没有足够的时间允许 计算。 Time Slice 时间分片 React 在渲染(render)的时候,不会阻塞现在的线程 如果你的设备足够快,你会感觉渲染是同步的 如果你设备非常慢,你会感觉还算是灵敏的 虽然是异步渲染,但是你将会看到完整的渲染,而不是一个组件一行行的渲染出来 同样书写组件的方式 react 项目遇到的问题react 项目问题 在react 项目中使用Echarts 的时候,在componentDidMount 中执行绘制图表的函数echarts。Init (#id),提示获取不到宽高,因此,绘制出来的图标呈现出压扁的状态或者没有绘制 解决办法:给compoentDidMount 中的drawCharts 方法加上一个延时器 说出react 要解决的核心问题是什么,他有哪些突出的技术创新 核心问题:react 的组件中state 只要以改变,就执行render,浪费资源 技术创新:通过虚拟dom 来实现dom 操作,避免频繁引起页面的重绘和回流,优化了性能; redux redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要 有三个核心方法,action,store,reducer 三大原则: 1)唯一数据源(整个应用的state 被储存在一棵object tree 中,并且这个object tree 只存在于 唯一一个store 中) 2)reducer 必须是纯函数(输入必须对应着唯一的输出) 3)State 是只读的, 想要更改必须经过派发action redux 的工作流程: 使用通过reducer 创建出来的Store 发起一个Action,reducer 会执行相应的更新state 的方法,当 state 更新之后,view 会根据state 做出相应的变化 1)提供getState()获取到state 2)通过dispatch(action)发起action 更新state 3)通过subscribe()注册监听器 flux 中数据监听,数据改变需要自己写,redux 中数据监听及修改会自己封装好,现在我们用的 是react-redux,它基于redux,使用了provider api ,将store 注册到全局,在组建中用connect 引入, 里面有两种方法,start-to props,dispath-to-props,这样就可以取到reducer 中的数据跟变量,数据修改 时,react 未做深度比较,redux 做深度拷贝,在项目中使用immutable redux 数据流通的过程 1)用户操作视图 2)发起一次dispatch。有异步:返回一个函数(使用thunk 中间件),没有异步:return {} 3)进入reducer,通过对应的type 去修改state,最后返回一个新的state redux 怎么用? 1:下载react-redux 模块 2:将redux 的库注册全局:在入口文件引入,暴露其中的Provider 方法,并将store 绑到Provider 组件上,将app 包裹起来, 3:在组件中使用connect,将组件传入,前面再传入属性及方法,在视图中使用props 调用 connect()前两个参数是什么? mapStateToProps(state, ownProps) 属性变量 允许我们将store 中的数据作为props 绑定到组件中,只要store 更新了就会调用mapStateToProps 方法,mapStateToProps 返回的结果必须是object 对象,该对象中的值将会更新到组件中 mapDispatchToProps(dispatch, [ownProps]) 方法 允许我们将action 作为props 绑定到组件中,如果不传这个参数redux 会把dispatch 作为属性注 入给组件,可以手动当做store.dispatch 使用 mapDispatchToProps 希望你返回包含对应action 的object 对象 属性,方法统一在props 调用 redux 与mobx 的区别? redux 将数据保存在单一的store 中,mobx 将数据保存在分散的多个store 中 redux 需要手动处理变化后的操作,mobx 数据变化后自动处理响应的操作 redux 状态不可变,只能读,不能修改,mbox 状态可变,可修改 Redux 比较复杂,但调试容易;mbox 比较容易,调试会比较困难,同时结果也难以预测。 mobx 更适合数据不复杂、短平快的项目 Redux 适合有回溯需求的应用比如一个画板应用、一个表格应用, 单一事实来源: Redux 使用“Store”将程序的整个状态存储在同一个地方。因此所有组件的状态都存储在Store 中,并且它们从Store 本身接收更新。单一状态树可以更容易地跟踪随时间的变化,并调试或检查 程序。 redux 中如何进行异步操作 异步中间件只有两种redux-thunk、redux-saga, Redux Thunk 的作用是什么 Redux thunk 是一个允许你编写返回一个函数而不是一个action 的actions creators 的中间件。 如果满足某个条件,thunk 则可以用来延迟action 的派发(dispatch),这可以处理异步action 的派发 (dispatch)。 Redux 的组件。 Action – 这是一个用来描述发生了什么事情的对象。 Reducer – 这是一个确定状态将如何变化的地方。 Store – 整个程序的状态/对象树保存在Store 中。Store 是一个JavaScript 对象,它可以保存程 序的状态,并提供一些方法来访问状态、调度操作和注册侦听器 View – 只显示Store 提供的数据。 Redux 中定义Action React 中的Action 必须具有type 属性,该属性指示正在执行的ACTION 的类型。必须将它们 定义为字符串常量,并且还可以向其添加更多的属性。在Redux 中,action 被名为Action Creators 的 函数所创建。 React Router v4 中使用switch 关键字 虽然
** 用于封装Router 中的多个路由 当你想要仅显示要在多个定义的路线中呈现的单个路线时,可以使用“switch” 关键字,使用 时, ** 标记会按顺序将已定义的URL 与已定义的路由进行匹配。找到第一个匹配项后,它将渲染指定的路径。从而绕过其它路线 怎样对比新旧state react-router 的原理 #BrowserRouter 或hashRouter 用来渲染Router 所代表的组件 Route 用来匹配组件路径并且筛选需要渲染的组件 Switch 用来筛选需要渲染的唯一组件 Link 直接渲染某个页面组件 Redirect 类似于Link,在没有Route 匹配成功时触发 #监听url 变化或者重写push.history,在重写的函数里增加回调。这样你就能在url 变化的时候获 取url,解析url,匹配路径所对应的组件,展示他。 #实现URL 与UI 界面的同步。其中在react-router 中,URL 对应Location 对象,而UI 是由react components 来决定的,这样就转变成location 与components 之间的同步问题。 React 与Angular 有何不同 react 是Facebook 出品,angular 是Google react 只有MVC 中的C,angular 是MVC react 使用虚拟DOM,angular 使用真实DOM react 是单项数据绑定,angular 是双向数据绑定 为什么建议传递给setState 的参数是一个callback 而不是一个对象 因为this.props 和this.state 的更新可能是异步的,不能依赖它们的值去计算下一个state。 调用setState 之后发生了什么 当调用setState 后,新的state 并没有马上生效渲染组件,而是,先看执行流中有没有在批量 更新中 如果有,push 存入到dirtyeComponent 中,如果没有,则遍历dirty 中的component,调用 updateComponent,进行state 或props 的更新 然后更新UI,react 进行diff 运算,与上一次的虚拟DOM 相比较,进行有效的渲染更新组件 setState 何时同步何时异步 1)setState 只在合成事件(react 为了解决跨平台,兼容性问题,自己封装了一套事件机制,代 理了原生的事件,像在jsx 中常见的onClick、onChange 这些都是合成事件)和钩子函数(生命周期) 中是“异步”的,在原生事件和setTimeout 中都是同步的 2)setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的, 只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后 的值,形式了所谓的“异步”,当然可以通过第二个参数setState(partialState, callback) 中的callback 拿到更新后的结果 3)setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件 和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次setState , setState 的 批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时setState 多个不同的值,在更 新时会对其进行合并批量更新 setState 的两个参数 第一个参数是要改变的state 对象 第二个参数是state 导致的页面变化完成后的回调,等价于componentDidUpdate 为什么建议传递给setState 的参数是一个callback 而不是一个对象 因为this.props 和this.state 的更新可能是异步的,不能依赖它们的值去计算下一个state。 React 中refs 的作用 Refs 是React 提供给我们的安全访问DOM 元素或者某个组件实例的句柄 我们可以为元素添加ref 属性然后在回调函数中接受该元素在DOM 树中的句柄 该值会作为回调函数的第一个参数返回 除了在构造函数中绑定this,还有其它方式吗 你可以使用属性初始值设定项(property initializers)来正确绑定回调,create-react-app 也是默认支持 的。在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。 组件的状态(state)和属性(props)之间有何不同react 组件 State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发 生突变,但多数时候是作为用户事件行为的结果 Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言, props 是不可变的 怎么阻止组件的渲染 在组件的render 方法中返回null 并不会影响触发组件的生命周期方法 在构造函数中调用super(props) 的目的是什么 在super() 被调用之前,子类是不能使用this 的,在ES2015 中,子类必须在constructor 中调 用super()。传递props 给super() 的原因则是便于(在子类中)能在constructor 访问this.props 组件不能改变自身的props,但是可以把其子组件的props 放在一起(统一管理) 应该在React 组件的何处发起Ajax 请求react ajax 在React 组件中,应该在componentDidMount 中发起网络请求。这个方法会在组件第一次“挂载”(被 添加到DOM)时执行,在组件的生命周期中仅会执行一次。更重要的是,你不能保证在组件挂载之前 Ajax 请求已经完成,如果是这样,也就意味着你将尝试在一个未挂载的组件上调用setState,这将不 起作用。在componentDidMount 中发起网络请求将保证这有一个组件可以更新了。 React 中有三种构建组件的方式react 构建组件 React.createClass():兼容性最好。一直都是react 官方唯一指定的组件写法 ES6 class:用类来实现,调用类实现的组件会创建实例对象。react 所有组件都继承自顶类 React.Component。他的定义很简介,只是初始化了React.Component 方法,声明了props,context,refs 等。并且在原型上定义了setState 和forceUpdate 方法。 无状态函数。没有state,没有生命周期方法。在适合的情况下,我们都应该且必须使用无状态 组件,无状态组件不会在调用时创建新实例。它创建时始终保持了一个实例。避免了不必要的内存分 配。做到了内部优化 react 性能优化, PrueComponent 或shouldComponentUpdate,react 中,由于在一个组件发生了重新render 后, 其所有的子组件都会发生重新render(默认情况下),即使传递给子组件的props 没有发生变化,因此, 我们可以通过shouComponentUpdate 钩子函数来通过前后props 的对比来判断传入的参数是否发生了 变化,可减少无用的render,PureComponent 也是重写了shouldCompoentUpdate 来进行了props 的 浅层对比。 react 组件加载、更新中会触发哪些过程? 更新触发 React 是数据(state/props)驱动的,state 的变化会触发render 函数的重新执行,而render 是生成虚拟dom 的关键。组件在第一次渲染后会执行一遍render 形成第一棵虚拟dom,后续组件中 state/props 的变化也会造成组件的重新渲染,而每一次的重新渲染都会触发新的虚拟dom 树的产生 与diff 比较(这也是为什么react 不允许用户自己改变state 而是用setState 方法去更新state), 再将不同点patch 到真实dom 上去,实现页面的更新。 前端面试话术:https://m.toutiao.com/i6632621431676994062/ 学习:码农网:码农书籍推荐,码农工具,教程 简书、掘金、力扣(算术题)、github(下载源码) 版本管理系统:gitlab bug 管理系统:禅道 自动化部署工具--发布:jenkins 解决点击事件300S 延迟 原因:用户在iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作, 当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操 作。因此,iOS Safari 就等待300 毫秒,以判断用户是否再次点击了屏幕 方法一:插件:tap.js 方法二:禁用缩放 Ts(typescript) Immutable:统一数据格式 Thunk:是支持一个函数 react 新特性 白屏: 项目问题 1 : 路径改为相对路径: 在config 文件夹中找到index.js 打开把assetsPublicPath: '/' 改成 assetsPublicPath: './',再次执行npm run build 就可以了。 2:未重定向, 3:兼容性问题,兼容低版本ie,banble-sole vcoson 移动端调试神器 版本 Vue 2.6.10 vue-cli 4.0.5 React 16.11.0 react-cli 3.2.0 移动端与pc 端不同 1、兼容性方面 移动端:主要是不同终端分辨率问题 PC 端: 主要在浏览器不同内核兼容性上问题 2、布局方面 移动端:移动端除了不同型号终端的分辨率问题还有同一终端的横屏竖屏处理,总体就是响应 式布局(自适应布局) PC 端: 通常有固定宽度(980px(也有960,1000,1200)),也就是版心,然后将版心居中 margin:0 auto; 3、js 方面 移动端:没有点击事件,只有触摸、滑动事件(点击、滑动、双击、双指放大、双指缩小、五 指收缩和苹果最新的3Dtouch 按压力度等) PC 端: 通常有固定宽度(980px(也有960,1000,1200)),也就是版心,然后将版心居中 margin:0 auto;(滑动、左击、右击、双击操作等) 4、css3 方面 移动端:手机游览器可能不兼容css3 的属性,可通过媒体查询增强代码健壮性或使用calc() 直接计算宽高 @media screen and (max-width: 750px) { //当宽度小于750px 时,执行花括号中的内容 } PC 端: 5:屏幕 6:更新:pc 端慢,移动端更新快 瀑布流 1:js 实现 瀑布流布局的特点是等宽不等高。 为了让最后一行的差距最小,从第二行开始,需要将图片放在第一行最矮的图片下面,以此类推。 父元素设置为相对定位,图片所在元素设置为绝对定位。然后通过设置top 值和left 值定位每个元 素。 2:column 多行布局实现瀑布流 column 实现瀑布流主要依赖两个属性。 一个是column-count 属性,是分为多少列。 一个是column-gap 属性,是设置列与列之间的距离。 3:flex 弹性布局实现瀑布流 flex 实现瀑布流需要将最外层元素设置为display: flex,即横向排列。然后通过设置flex-flow:column wrap 使其换行。设置height: 100vh 填充屏幕的高度,来容纳子元素。每一列的宽度可用calc 函数 来设置,即width: calc(100%/3 - 20px)。分成等宽的3 列减掉左右两遍的margin 距离。 项目开发流程

你可能感兴趣的:(js,前端小技巧,vue,vue.js,javascript,node.js)