问答(45min)

  1. 自我介绍
  2. Vue通信机制有哪些
    1
    2
    3
    父子组件通信:props/$emit、$parent/$children和$ref、provide/inject、$attrs/listeners,
    兄弟组件通信:Bus中央事件总线(使用了Vue.$emit和Vue.$on),Vuex
    跨级组件通信:Bus、Vuex、provide/inject、$attrs/listeners,
  3. 水平垂直居中实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    .parent{
    position:relative;
    }
    .box{
    width:100px;
    height:100px;
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%,-50%)
    //或者
    margin-left:-50px;
    margin-top:50px;
    }
    .box{
    display:flex;
    justify-content:center;
    align-itrem:center
    }
  4. 实现一个左边固定,右边自适应布局
    1
    2
    3
    4
    5
    6
    <body>
    <div class="parent">
    <div class="left"></div>
    <div class="right"></div>
    </div>
    </body>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    1. float: left+ margin-left;float使左边的元素脱离文档流,右边的元素可以和左边的元素显示在同一行,设置margin-left让右边的元素不覆盖掉左边的元素, 代码如下:
    .left {
    float: left;
    width: 200px;
    height: 100px;
    background-color: green;
    }

    .right {
    margin-left: 200px;
    height: 100px;
    background-color: yellow;
    }
    2. position: absolute + margin-left左边绝对定位,右边设置margin-left,代码如下:
    .left {
    position: absolute;
    width: 200px;
    background-color: green;
    height: 100px;
    }

    .right {
    margin-left: 200px;
    background-color: yellow;
    height: 100px;
    }
    3. flex布局可以使两个子元素显示在同一行,只要左边的宽度固定,就可以实现效果, 代码如下:
    .parent {
    display: flex;
    margin: 0 auto;
    max-width: 1000px;
    height: 100px;
    }
    .left {
    width: 200px;
    background-color: green;
    }

    .right {
    flex: 1;
    background-color: yellow;
    }
    4.float+overflow:hidden 这种办法主要通过 overflow 触发 BFC,而 BFC 不会重叠浮动元素
    .left {
    float: left;
    width: 200px;
    height: 100px;
    background-color: green;
    }

    .right {
    overflow: hidden;
    height: 100px;
    background-color: yellow;
    }
  5. 跨域是啥?跨域有哪些?
    1
    2
    3
    4
    5
    6
    7
    浏览器同源策略:同协议、域名、端口
    document.domain+ iframe
    JSONP
    window.postMessage()
    CORS
    > 普通跨域请求:只需服务器端设置Access-Control-Allow-Origin;浏览器发现这次跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段
    > 带cookie跨域请求:前后端都需要进行设置;根据xhr.withCredentials字段判断是否带有cookie;服务端同意带cookie:Access-Control-Allow-Credentials: true;Access-Control-Allow-Origin就不能设为星号
  6. Vue父子组件的执行流程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    创建初始化阶段:
    父:beforeCreate
    父:created
    父:beforeMount
    子:beforeCreate
    子:created
    子:beforeMount
    子:mounted
    父:mounted

    更新组件阶段:
    父:beforeUpdate
    子:beforeUpdate
    子:updated
    父:updated

    销毁阶段:
    父:beforeDestroy
    子:beforeDestroy
    子:destroyed
    父:destroyed
  7. 浏览器一帧发生了啥?
    略
  8. 原生Ajax实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function myAjax(url,method='GET',data=null) {
    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
    data = data ? queryStringify(data) : data
    if(method == 'POST') {
    xhr.open(method,url,true)
    xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
    xhr.send(data)
    }else{
    if(data) url = url + '?' + data
    xhr.open(method,url,true)
    xhr.send()
    }
    xhr.onreadystatechange = function() {
    if(xhr.readystate == 4) {
    if(xhr.state == 200) {
    console.log(xhr.responseText)
    }
    }
    }
    function queryStringify(obj) {
    var res = ''
    for(var key in obj) {
    res += key + '=' + obj[key] + '&'
    }
    return res.substring(0,res.length - 1)
    }
    }
  9. let,const,var区别
    1
    2
    3
    let,const 块级作用域,无声明提前;
    var无块级作用域,声明提前;
    const 一般定义常量(声明要赋值,不然报错),保存基本数据类型或地址指针,不能改变其保存的值;但可以改变其对象的属性(因为保存的对象地址指针并没有改变);
  10. 怎么实现const里面的属性不能修改?
    1
    2
    3
    Object.defineProperty(obj,'a',{writable:false})
    Object.freeze(obj) //冻结 不能修改属性 相当于writable:false
    Object.seal(obj) //封存 不能删除 相当于configurable:false
  11. Promise.all() 怎么实现?这么知道执行完成了?
    1
    2
    用处:并行执行一系列异步操作,返回结果集。
    详解:https://www.jianshu.com/p/c8af0c130ccb
  12. 原型链是啥?
    1
    2
    JavaScript是面向对象的,每个实例对象都有一个__proto__属性,该属性指向它的原型对象,这个实例对象的构造函数有一个原型属性prototype,与实例的proto属性指向同一个对象。当一个对象在查找一个属性的时候,自身没有就会根据__proto__向它的原型进行查找,如果都没有,则向它的原型的原型继续查找,直到查到Object.prototype.proto_为null,这样也就形成了原型链。
    作用:共享属性和方法
  13. new的原理
    首先新建一个对象,链接到原型,绑定this,返回这个对象。
    1
    2
    3
    4
    5
    6
    7
    8
    function New(Fn) {
    let obj = {}
    let arg = Array.prototype.slice.call(arguments, 1)
    obj.__proto__ = Fn.prototype //链接到原型
    obj.__proto__.constructor = Fn //构造函数改变
    Fn.apply(obj, arg) //绑定this
    return obj
    }
  14. this的指向有哪些?
    1
    2
    3
    4
    5
    (1) 作为函数调用,非严格模式下,this指向window,严格模式下,this指向undefined;
    (2) 作为某对象的方法调用,this通常指向调用的对象。
    (3) 使用apply、call、bind 可以绑定this的指向。
    (4) 在构造函数中,this指向新创建的对象
    (5) 箭头函数没有单独的this值,this在箭头函数创建时确定,它与声明所在的上下文相同。
  15. 怎么改变this的指向?
    call()、bind()、apply()
  16. call()、bind()、apply() 区别
    首先他们都可以改变this的指向;在传参方面,第一个参数都是目标对象(要把this指向的对象),其他参数;call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。bind改变this不会立即执行,call、apply会立即执行;
  17. Vue数据响应式原理
    略
  18. css盒子模型、BFC
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    盒子组成部分 = 内容(content) + padding(内边距) + border(边框) + margin(外边距)
    标准盒模型中width指的是内容区域content的宽度;height指的是内容区域content的高度。
    怪异盒模型中的width指的是内容、边框、内边距总的宽度(content + border + padding);height指的是内容、边框、内边距总的高度
    改变box-sizing:
    > content-box: 默认值,border和padding不算到width范围内,可以理解为是W3c的标准模型(default)
    > border-box:border和padding划归到width范围内,可以理解为是IE的怪异盒模型
    > padding-box:将padding算入width范围
    BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域;
    BFC的布局规则
    内部的Box会在垂直方向,一个接一个地放置。
    Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
    每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
    BFC的区域不会与float box重叠。
    BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    计算BFC的高度时,浮动元素也参与计算。
    如何创建BFC
    > 1、float的值不是none。
    > 2、position的值不是static或者relative。
    > 3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
    > 4、overflow的值不是visible
  19. 父元素高度塌陷解决方案
    1
    2
    3
    4
    (1)给父元素设置高度
    (2)给父元素添加:overflow:hidden/auto/scroll都可以清除浮动
    (3)给浮动元素末尾添加空标签,给空标签添加clear:both
    (4)伪元素清除法:::after{content:"";display:block;clear: both;height:0;overflow: hidden;visibility: hidden;}
  20. requestAnimationFrame/requestIdleCallback
    略
  21. session、cookie、localStorage 、sessionStorage
    1
    2
    3
    4
    5
    6
    7
    8
    cookie机制:如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。
    localStorage:localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失;
    sessionStorage的生命周期是在仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。
    setItem (key, value) —— 保存数据,以键值对的方式储存信息。
    getItem (key) —— 获取数据,将键值传入,即可获取到对应的value值。
    removeItem (key) —— 删除单个数据,根据键值移除对应的信息。
    clear () —— 删除所有的数据
    key (index) —— 获取某个索引的key
  22. HTTP强缓存和协商缓存
    略
  23. 有缓存返回的状态码(200)
  24. 页面布局响应实现?(媒体查询)
  25. http网络状态码有哪些(200、301、302、304、404、500)
  26. 301和302的区别(永久重定向、临时重定向)
  27. 前端安全XSS、CSRF(跨站脚本攻击、跨站请求伪造)
  28. 说说Vue的mixins?(不咋了解 ,逻辑相同提取公共代码)
    1
    2
    3
    两个组件引入同一个mixins,混入对象的值在两个组件中是相互独立的。
    组件中和mixins中有同样的方法,组件中的会覆盖mixins中的;
    如果mixins和组件中含有相同的生命钩子函数,会先执行mixins里面的,然后执行组件中的
    非全面(有些想不起来了)

    编程题 (20min)

  29. JSONP实现
    1
    2
    3
    4
    5
    function Jsonp(src){
    var script = document.createElement('script')
    script.src = src
    document.getElementsByTagName('head')[0].appendChild(script)
    }
  30. 大数相加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     // input: a,b (string)
    //output: string
    function bigAdd(a,b) {
    let aLen = a.length
    let bLen = b.length
    let len = aLen > bLen ? aLen : bLen //取最长的字符串
    //以 0 补位
    if(aLen > bLen){
    var str = ''
    for(var i = 0; i < (aLen - bLen); i++) {
    str += '0'
    }
    b = str + b
    }else{
    var str = ''
    for(var i = 0; i < (bLen - aLen); i++) {
    str += '0'
    }
    a = str + a
    }
    //反转字符串,从个位开始计算
    a = a.split('').reverse()
    b = b.split('').reverse()
    //字符串转number
    a = a.map((value,index)=>{
    return parseInt(value)
    })
    b = b.map((value,index)=>{
    return parseInt(value)
    })
    let carryAdd = 0 //进位
    let res = []
    for(var i = 0; i < len; i++) {
    if(a[i] + b[i] + carryAdd >= 10) {
    res[i] = a[i] + b[i] - 10 + carryAdd
    carryAdd = 1
    if(i == len - 1) res[i + 1] = 1 //最后一位进位
    }else{
    res[i] = a[i] + b[i] + carryAdd
    carryAdd = 0
    }
    }
    return res.reverse().join('')
    }
    console.log(bigAdd('369222222','359222222'))