问答(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
    letconst 块级作用域,无声明提前;
    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: 默认值,borderpadding不算到width范围内,可以理解为是W3c的标准模型(default)
    > border-boxborderpadding划归到width范围内,可以理解为是IE的怪异盒模型
    > padding-box:将padding算入width范围
    BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域;
    BFC的布局规则
    内部的Box会在垂直方向,一个接一个地放置。
    Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Boxmargin会发生重叠。
    每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
    BFC的区域不会与float box重叠。
    BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    计算BFC的高度时,浮动元素也参与计算。
    如何创建BFC
    > 1、float的值不是none
    > 2、position的值不是static或者relative
    > 3、display的值是inline-blocktable-cellflextable-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'))