2019年4月份面试总结

js部分

1. var let const 的理解

let /const 存在变量的声明和提升, 只是没有初始化分配内存。
一个变量赋值有三个操作:

  • 声明(作用域提升到顶部)
  • 初始化(赋默认值)
  • 赋值(继续赋值)

var 变量声明提升,初始化为 undefined,代码执行到的时候进行赋值
let 变量声明提升, 没有初始化内存,代码执行到的时候进行赋值
const 只有变量的声明和初始化,没哟赋值操作 所以不可变

const 只是保证了指向的内存地址不变,而不是内部数据结构不变,确保不会被其他的值所代替

2. 浅拷贝和深拷贝

浅拷贝: 创建一个新的对象,把原有的对象属性完整的拷贝过来,包括了原始类型的值,引用类型的地址
常用的浅拷贝的方式: Object.assign() , Array.prototype.sliceArray.prototype.contact() ;以及es6中的扩展运算符。

深拷贝: 完整的拷贝出不同的两个数据

一行代码解决:JSON.parse(JSON.stringify(arr)) 使用该方式可能会出现递归爆栈的情况。

手写一个深拷贝:

function deepCopy(data) {
    let o;
    let t = typeOf(data)
    if(t === 'object') {
        o = {}
    }else if (t === 'array') {
        o = []
    }else {
        return data
    }

    if(t === 'object') {
        for(let i in data) {
            o[i] = deepCopy(data[i])
        }
    }else if (t === 'array') {
       for (let j of data) {
           o.push(deepCopy(data[j]))
       }
    }

    return o;
}

3. js的数据类型有哪些?其中基本数据类型有哪些?

数据类型有: Boolean , null , undefined , Number , String , Symbol , Object

除过 Object 以外均为基本类型

4. typeof 和 instanceof

typeof 对于原始类型来说,除了null都可以正确的显示, null为object, 对象类型也都显示 object

instanceof 是通过原型链来进行判断,可以判断一个对象的正确类型, 用来判断基本类型是不行的

var str = 'hello world' 
str instanceof String //false

5. 如何正确判断this? 箭头函数的this是什么?

this是动态进行绑定的,取决于上下文的函数调用的条件(函数调用的位置)

箭头函数是没有this的绑定的,为父级作用域的this

6. 什么是闭包?

函数a内部有一个函数b, 函数b可以访问函数a中的变量, 那么函数b就是闭包。
闭包存在的意义就是可以间接的访问函数内部的变量。

7. null 和 undefined

相同点:

  • 在if判断语句中,值都默认为false;
  • 两者都代表无

不同点:

  • null转为Number为0, undefined则为NaN
  • undefined是代表一个值,而该值没有赋值
  • null为一个特殊的对象
  • 设置为null的变量或者对象会被收集器回收

8. 如何理解原型?如何理解原型链?

  • 每个函数都有一个 prototype (原型)属性,属性是一个对象,这个对象存储了当前类供实例调取使用的公共属性和方法。
  • 在“浏览器默认”给原型开辟的内存中有一个属性 constructor , 存储的是当前类的本身。
  • 每个对象(实例)都有一个 __proto__ 的原型链属性, 这个属性指向的是当前实例所属类的原型(不确定所属的类,都指向 Object.prototype
  • Object 是js内置的基类,__proto__null

原型链是由原型对象组成, 每个对象都有 __proto__ 属性,指向了创建该对象的构造函数原型。__proto__ 将对象连接起来组成了原型链, 是一个用来实现继承和共享属性的有限对象链。

  • 属性查找机制: 当查找对象的属性时,如果实例对象自身不存在,则沿着原型链往上一级查找,找到则输出。不存在则继续沿着原型链往上一级查找, 直到顶级的原型对象 Object.prototype ,如果还没有找到,则输出undefined。
  • 属性修改机制: 只会修改实例对象本身的属性。如果不存在,则进行添加该属性,如果修改原型的属性可以用 b.prototype.x = 2,会导致所有的继承与该对象的实例属性发生改变。

9. 事件的触发过程是怎么样的?什么是事件代理?

事件触发的三个阶段:
1, Window往事件触发处,遇到注册的捕获事件会触发
2. 传播到时间触发注册的事件
3. 从事件触发处往window传播,遇到注册的冒泡事件触发

特例: 给body的子节点中,同时注册冒泡和捕获事件,事件会按照注册的顺序执行。

事件代理: 若需要子节点注册事件的话,应注册在父节点上

  1. 节省内存
  2. 不需要给子节点注销事件
  • cookie: 一般有服务器生成,可以设置过期事件,大小4k左右,每次请求会携带在header中,对于请求的性能有影响
  • localStorage: 除非被清理,否则一直在;大小为5M; 不参与服务器通信
  • sessionStorage 页面关闭就清理;大小为5M; 不参与服务器通信

对于cookie来说,需要注意安全性
value不能使用明文标识
http-only 不能通过js访问cookie, 减少XSS攻击

11. 基础排序算法

冒泡排序:两两进行比较

function sort(arr) {
    let len = arr.length;
    for(var i = 0; i < len; i++) {
        for(var j = 0; j < len - j - 1; j++) {
            if(arr[j] > arr[j+1]) {
                [arr[j] , arr[j+1]] = [arr[j+1] , arr[j]]
            }
        }
    }
}

选择排序: 遍历自身以后的元素, 最小的元素跟自己调换位置

function selectSort(arr) {
    let len = arr.length;
    for(var i = 0; i < len; i++) {
        for(var j = i; j < len; j++) {
            if(arr[j] < arr[i]) {
                [arr[i] , arr[j]] = [arr[j] , arr[i]]
            }
        }
    }
}

vue相关

css部分

浏览器及网络

1. http状态码

http 状态码负责标识客户端http请求的返回结果,标记服务器端的处理是否正常,通知出现的错误等工作。 状态码的类别:

  • 1xx 信息性状态码 接受的请求正在处理
  • 2xx 成功状态码 请求正常处理完毕
  • 3xx 重定向状态码 需要进行附加操作已完成请求
  • 4xx 客户端错误状态码 服务器无法处理请求
  • 5xx 服务器错误状态码 服务器处理请求出错

200 请求已经正常处理 204 请求处理成功,但资源没有返回结果 206 对资源某一部分的请求

301 资源的URI已更新
302 资源的URI已临时定位到其他位置
303 表示请求对应的资源存在着另一个URI,应使用get请求的资源
304 资源已经找到,但未符合条件请求
307 临时重定向

400 请求报文中存在语法错误
401 表示发送的请求需要通过http认证
403 对请求资源的访问被服务器拒绝
404 服务器上没有请求的资源

500 服务daunt发生了错误
503 服务器处于超负载或正在进行停机维护

2. load 和 DOMContentLoaded

  • load事件触发代表页面中的 DOm, css, js, img已经全部加装完毕
  • DOMContentLoaded事件触发代表初始HTML被完全加载和解析, 不需要等待css, js, 图片的加载

3. 重绘(Repaint)和 回流(Reflow)

重绘和回流是渲染步骤中的小节, 对性能影响很大

重绘是当前节点需要更改外观而不影响布局
回流是布局或者几何属性需要改变
回流一定发生重绘,重绘不一定回流

减少重绘和回流:

  1. 使用 translate 代替 top
  2. 使用 visibility 替换 display:none
  3. 把DOM离线后修改 , 先把DOM给display:none 然后修改,在显示出来
  4. 不要将DOM结果的属性放在循环中
  5. 不要使用table布局,可能很小的改动会造成整个table重新布局
  6. 选择使用requestanimation
  7. css选择服从右往左匹配查找, 避免DOM深度过深
  8. 频繁运行的动画变为图层

4. 从敲回车开始到页面展现这个过程发生了什么

  1. dns查询
  2. 建立TCP连接
  3. 发送http请求
  4. 后台处理
  5. 接收响应
  6. 接收完成
  7. 读取html中的DOCTYPE
  8. 逐行解析
  9. link,script 会像服务器发生请求

3. 相关性能优化:

  1. 减少DNS查询, 没有DNS缓存的情况
  2. 使用懒加载和预加载
  3. 使用CDN
  4. 使用gzip压缩资源, 一般都是HTML脚本样式
    请求头: Accept-Encoding: gzip, deflate
    响应头: Content-Encoding: gzip
  5. cache-control
    比如设置:cache-control:max-age:30
    表示30s内遇到同样的请求会刷新页面, 会直接读取缓存
  6. 用没有cookie的域名提供资源 防止cookie 增加网络流量
  7. 使用link而不是 @import
  8. 减少/最小化http请求次数 合并js文件,css文件
  9. 事件委托 基于事件冒泡
  10. tcp连接复用
    在HTTP/1.1中新增keep-alive 功能,当浏览器连接TCP后, 新的请求可以在上次建立的 tcp 连接之上发送,连接可以复用。
Last Updated: 4/23/2019, 12:16:03 AM