年后求职,这些基础你都会了吗?(更新中...)

123 阅读9分钟

年后求职,这些基础你都会了吗?(更新中...)

js相关

javascript 的数据类型

基本类型

  • String: 文本字符串.
  • Number: 整数和浮点数.
  • Boolean: 表示 真 (true) / 伪 (false) 的两个特殊值.
  • Null: 表示空值.
  • Undefined: 表示未定义或者不存在.
  • Symbol: 表示独一无二的值, 可以保证不会与其他属性名产生冲突.
  • BigInt: 能够支持比 Number 类型的范围更大的整数值类型. 应用类型 对象object

let,const,var 有什么区别

(1)块级作用域: 块作用域由 { }包括,letconst 具有块级作用域,var 不存在块级作用域。块级作用域解决了 ES5 中的两个问题:

  • 内层变量可能覆盖外层变量
  • 用来计数的循环变量泄露为全局变量

(2)变量提升: var 存在变量提升,letconst 不存在变量提升,即在变量只能在声明之后使用,否在会报错。

(3)给全局添加属性: 浏览器的全局对象是 windowNode 的全局对象是 globalvar 声明的变量为全局变量,并且会将该变量添加为全局对象的属性,但是 letconst 不会。

(4)重复声明: var 声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历。constlet 不允许重复声明变量。

(5)暂时性死区: 在使用 letconst 命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用 var 声明的变量不存在暂时性死区。

(6)初始值设置: 在变量声明时,varlet 可以不用设置初始值。而 const 声明变量必须设置初始值。

(7)指针指向: letconst 都是 ES6 新增的用于创建变量的语法。 let 创建的变量是可以更改指针指向(可以重新赋值)。但 const 声明的变量是不允许改变指针的指向。

如何判断一个变量是数组

  • isArray() 方法
    • console.log(Array.isArray(arr))
  • 对象原型(通过原型链判断是否具有和数组同一原型链的顶端。)
    • console.log(arr.__proto__ === Array.prototype) arr.__proto__ === Array.prototype; // true
  • instanceof 运算符
    • console.log(arr instanceof Array) arr instanceof Array; // true
  • Object.prototype.toString.call()
    • Object.prototype.toString.call()

数组去重

  • 利用Set()+Array.from()
  • 利用两层循环+数组的splice方法
  • 利用数组的indexOf方法\includes方法
  • 利用数组的filter()+indexOf()

JS数组去重的方式详细总结(7种)

数组的方法

    • push
    • unshift
    • concat
    • pop
    • shift
    • slice
    • splice
    • indexOf
    • includes
    • find
  • 排序
    • reverse
    • sort
  • 转化
    • join
  • 迭代方法
    • some
    • every
    • forEach
    • filter
    • map

数组方法

字符串的常用方法

  • 操作方法
    • 增(concat)
    • 删(slice、substr、substring)
    • 改(toLowerCase、toUpperCase)
    • 查(indexOf、chatAt、includes、startWith)
  • 转换方法
    • split
  • 模版匹配方法
    • match
    • search
    • replace

JavaScript 中的类型转换机制

  • 显示转换(Number、parselnt、String、Boolean)
  • 隐式转换
    • 比较运算符
    • 算术运算符

深拷贝与浅拷贝

  • 基本类型数据保存在在栈内存中
  • 引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中
  • 浅拷贝
    • Object.assign
    • slice
    • concat
  • 深拷贝
    • JSON.stringify() 弊端:会忽略undefinedsymbol函数
    • _.cloneDeep()

typeof与instanceof

  • typeof
    • 操作符返回一个字符串,表示未经计算的操作数的类型
    • typeof 1 // 'number'
  • instanceof
    • 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
    • object instanceof constructor
  • 区别
    • typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
    • instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
    • typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断
    • 如果需要通用检测数据类型,可以采用Object.prototype.toString,调用该方法,统一返回格式“[object Xxx]”的字符串

原型和原型链

  • 原型:每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。
  • 原型链:任何一个对象,都有原型对象,原型对象本身又是一个对象,所以原型对象也有自己的原型对象,这样一环扣一环就形成了一个链式结构,我们把这个链式结构称为:原型链。

prototype 和 __proto__ 区别是什么?

  • prototype是构造函数的属性。
  • __proto__ 是每个实例都有的属性,可以访问 [[prototype]] 属性。
  • 实例的__proto__ 与其构造函数的prototype指向的是同一个对象。

说说闭包

  • 闭包就是有权访问另一个函数内部变量的函数。
  • 闭包产生的原因:内部函数存在对外部函数局部变量的引用就会导致闭包。
  • 闭包会造成内存泄漏
    • 闭包会包含其他函数的作用域,会比其他函数占据更多的内存空间,不会在调用结束之后被垃圾回收机制回收,过度使用闭包会过度占用内存,造成内存泄漏。

ES6

箭头函数

  • 相比普通函数,箭头函数有更加简洁的语法。
  • 箭头函数不绑定this,会捕获其所在上下文的this,作为自己的this。
  • 使用call,apply,bind并不会改变箭头函数中的this指向。
  • 箭头函数是匿名函数,不能作为构造函数,不可以使用new命令,否则抛出错误。
  • 箭头函数没有原型对象prototype这个属性

这一次,彻底搞懂箭头函数

前端项目性能优化

  • 页面加载及渲染过程的优化
    • 避免多层css
    • 避免频繁操作dom
    • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
    • 合理使用v-if,v-for,避免频繁操作 DOM
    • 图片加载优化(使用webp格式图片、设置适当的分辨率、使用雪碧图、使用占位图片)
    • 事件委托,利用JS事件冒泡机制把原本需要绑定在子元素的响应事件(click、keydown……)委托给父元素,减少内存占用,减少事件注册。
  • 渲染完成后的页面交互优化
    • 防抖节流

前端必会的图片懒加载(三种方式)
事件委托
防抖节流
图片加载优化

promise

  • Promise是异步编程的一种解决方案
  • 三种状态 pending(进行中) fulfilled(已成功)rejected (已失败)
  • 三个实例方法 then() catch() finally()
  • 构造函数方法 all() race() allSettled() resolve() reject() try()

面试官:你是怎么理解ES6中 Promise的?使用场景?

VUE相关

v-model双向绑定原理

  • 通过 v-bind:value 绑定变量,每次输入内容的时候触发input事件
  • 通过事件对象参数 event.target.value 获得输入的内容,并且把这个内容赋值变量

vue响应式原理

  • Vue2.0实现MVVM(双向数据绑定)的原理是通过 Object.defineProperty 来劫持各个属性的setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
  • Vue 3.0实现响应式基于ES6的Proxy。

区别:

VUE2
  • 1、基于Object.defineProperty,不具备监听数组的能力,需要重新定义数组的原型来达到响应式。
  • 2、Object.defineProperty 无法检测到对象属性的添加和删除 。
  • 3、由于Vue会在初始化实例时对属性执行getter/setter转化,所有属性必须在data对象上存在才能让Vue将它转换为响应式。
  • 4、深度监听需要一次性递归,对性能影响比较大。
VUE3
  • 1、基于Proxy和Reflect,可以原生监听数组,可以监听对象属性的添加和删除。
  • 2、不需要一次性遍历data的属性,可以显著提高性能。
  • 3、因为Proxy是ES6新增的属性,有些浏览器还不支持,只能兼容到IE11 。

虚拟 dom 是什么,为什么要使用虚拟 dom

diff 算法中 key 是做什么用的

用 index 做 key 会有什么问题吗,为什么不推荐使用 index 做 key

用 index 拼接一个随机字符串做 key 可以解决上述的问题吗

diff与DOM相关问题

http相关

从输入URL到页面加载的全过程?

  • URL解析
  • DNS查询
  • TCP连接
  • http请求
  • 响应请求
  • 页面渲染

URL到页面加载的全过程

TCP三次握手 四次挥手

  • 三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个报文。
    • 客户端向服务器发送SYN包,请求建立连接。该包中包含一个随机生成的初始序列号ISN(Initial Sequence Number)。
    • 服务器收到SYN包后,向客户端发送SYN+ACK包,表示同意建立连接。该包中也包含一个随机生成的序列号ISN,同时将确认序列号ACK设置为客户端的ISN+1。
    • 客户端收到服务器的SYN+ACK包后,向服务器发送ACK包,表示客户端也同意建立连接。该包的序列号设置为服务器的ISN+1,确认序列号设置为服务器的ISN+1。
      在三次握手完成后,TCP连接建立成功,双方可以开始进行数据传输。这个过程可以确保连接的可靠性和完整性,防止数据包的丢失或重复传输。

三次握手

跨域

跨域是浏览器受同源(协议、域名、端口)策略的限制,不允许不同源的站点之间进行某些操作(如发送ajax请求,操作dom,读取cookie),如果不进行特殊配置是不能操作成功的

解决方法

  • 前端通过脚手架或webpack配置devSever下的proxy选项,将/api开头的请求转发到真实服务器上。
  • CORS后端设置请求头
  • nginx反向代理

九种跨域方式实现原理(完整版)

http 状态码都有哪些

状态码第一位数字决定了不同的响应状态,如下:

  • 1 表示消息
  • 2 表示成功
  • 3 表示重定向
  • 4 表示请求错误
  • 5 表示服务器错误