前端面试题整理 [javascript]

bom和dom

bom

概念:浏览器对象模型,将浏览器看做了一个对象

顶级对象: window

包含关系: bom是包含dom的

常见的api: location、navigator、screen、setInterval/setTimeout、locstorage、sessionStorage

浏览器常见缓存的区别

locstorage

大小:5~20MB

生命周期:永久,手动清除

api使用:方便

sessionStorage

大小:5~20MB

生命周期:窗口关闭

api使用:方便

cookie

大小:4KB

生命周期:时间设置

请求:自动携带

api使用:不方便(js-cookie)

dom

概念: 文档对象模型, 将网页文档看做了一个对象

顶级对象 :document

包含关系: 被bom包含因为document是在window上,所以dom是属于bom的

常见api: getElementById getElementByTagName querySelector querySelectorAll

slice和splice两者的区别

  • slice 用于截取, 参数1,开始的位置,参数2结束的位置(不包含)
  • splice: 用于删除/新增 参数1: 开始的位置,参数2: 删除的个数, 参数3和参数3之后的所有参数新增的数据

substr和subString

  • substr: 用于截取,参数1: 开始的位置,参数2截取的个数
  • substring: 用于截取,参数1: 开始的位置,参数2: 结束的位置(不包含)

使用过哪些es6?

函数

 聊一聊promise

概念

promise是一个对象/构造函数,es6新增的,更加灵活的处理异步,也可以解决回调地狱问题

promise有三种状态:pending fullfield rejected状态不可逆 pending => (resolve)fullfield,pending =>(rejecte) rejected

实例方法
  • then方法:接收promise处理后的结果,
    • 第一个回调接收成功的结果,第二个回调用于接收失败的结果
    • then支持链式调用,在then中可以返回新的promise,并且调用resolve,会将成功的结果传递到下一个then中,所以借助then的链式解决了回调地狱的问题
    • 具备穿透性:在then中通过返回的promise调用resolve传递数据,下一个then如果没有通过回调进行接收,则会继续向下传递
    • then的返回值是promise,而且then的成功回调如果返回的不是promise,也会被then的promise的resolve进行处理
    • 终止then的成功回调的链式:reject、throw Error Promise.reject
  • catch方法:专门处理失败的状态
  • finnaly方法:都会执行
静态方法
  • all:同时处理多个异步,语法参数为数组,数组每一项是Promise实例,只有所有异步处理成功,才会进入then的成功回调,有一个失败,进入all的then的失败回调,结果是数组,值对应的就是参数数组的顺序
  • allsettled:语法基本和all一致,不管处理的异步中是否调用reject,最终都会进入allsettled的成功回调,在成功的回调中,数组每一项是对象,对象会有status,状态,成功或失败,还有value就是异步处理的结果
  • race:语法基本和all一致,可以获取到异步处理最快的那一个,在then中通过成功回调或失败回调获取结果
  • any:语法基本和all一致,可以获取到异步处理成功最快的那一个
async和await

promise的终极解决方案是async await

await 用来修饰promise, 当然await也可以修饰非promise,如果修饰的不是promise则会将 await后面的内容包装为promise,await的返回值会一直是promise的resolve处理,await下面的代码相当于是promise的then成功回调的代码,所以await下面的代码属于异步微任务

async用来修饰await就近的函数,被async修饰的函数,该函数返回值为promise,内部如果return数据,则该数据被promise的resolve进行处理,所以需要通过函数的then的成功回调获取期结果

async和await实际是generator的语法糖

Generator

概念: 也是es6的,可以将函数的控制权交出,也可以利用generator更方便的控制异步,实际async和await就是他的语法糖

区分: 星号

如何交出控制权: 通过yield进行控制权交出,通过next逐步调用

如何处理异步: 可以通过yield配合promise达到类似async和await的效果,通过yiled返回promise,在promise中处理异步,等异步成功调用resolve,这样在外部可以通过next.value获取到promise,通过then等待成功后,执行下一次的next

而且对应的自执行generator函数有co库,可以去自执行generator

区别:

new的过程

创建一个新对象

// 将新对象的__proto__ 指向了 Person.prototype

// 将构造函数内部的this指向新对象

// 执行构造函数给this(实例对象)添加属性或方法

// 默认return this

// 如果写了return 看 数据类型

// 数据类型是简单数据类型: return简单数据类型忽略 最终还是return this

// 如果数据类型是复杂数据类型: 最终得到是该复杂数据类型 return this无效

 字符串反转

'hello'.split('').reverse()

forin/forof区别

for in:一般用来遍历对象,并且可以遍历原型对象,不建议循环数组,可以循环

for of:不可以进行遍历普通对象的,可以遍历数字字符串数组和 newSet 对象等等,并且可以进行 break 终止,不可以 return

中断for

  • continue:终止该次循环,进入下一次,使用所有循环结构
  • break:跳出循环,执行循环后的语句,如果多层循环,只会退出当前层循环
  • return:终止循环,结束当前方法

统计数组中出现次数最多的元素

// 统计出出现次数最多的元素 返回次数和元素
  const arr = [1, 2, 3, 2, 3, 2, 3, 7, 8, 7, 6, 7, 5, 7, 0, 7, 7, 7, 7, 2, 5, 5, 5, 5, 5, 5]

  function repeatCount(arr) {
    // key 是元素 value: 次数
    const obj = {}
    let max = 0
    let maxItem = null
    for (let i = 0; i < arr.length; i++) {
      const item = arr[i]
      if (obj[item]) {
        obj[item]++
      } else {
        obj[item] = 1
      }
      if (obj[item] > max) {
        max = obj[item]
        maxItem = item
      }
    }
    console.log(maxItem, max)
  }

  repeatCount(arr)

 递归使用场景

export function transListToTree(data, pid) {
  const arr = []
  data.forEach((item) => {
    if (item.pid === pid) {
      // 当前: item 就是1级数据 item.id
      const children = transListToTree(data, item.id)
      if (children.length) {
        item.children = children
      }
      arr.push(item)
    }
  })
  return arr
}

聊一聊异步

为什么有异步?

js是单线程,如果js语言是多线程,在操作dom容易混乱,所以js就是单线程,问就是,如果某一个任务比较耗时,阻塞运行,js把耗时交给浏览器执行,交给浏览器执行的这些耗时任务: 异步任务

js在es5之前无法发起异步,es6的Promise可以发起异步

异步执行流程

  1. 主线程先判断任务类型
    • 如果是同步任务,主线程自己执行
    • 如果是异步任务,交给宿主环境(浏览器)执行
  1. 浏览器进行异步任务的执行,每个异步执行完后,会将回调放进任务队列,先执行完成的先放进任务队列,依次放入
  2. 等主线程任务全部执行完后,发现主线程没有任务可执行了,会取任务队列中的任务,由于任务队列里是依次放入进来的,所以取得时候也会先取先进来的,也就是先进先出原则
  3. 在任务队列中取出来的任务执行完后,在取下一个,依次重复,这个过程也称为 eventLoop 事件轮训

异步的解决方案

  • 回调
  • promise
  • async await
  • generator

es6模块化和commonjs模块化的区别

  1. es模块化的导入: import import {} import * as
  2. es6模块化的导出: export export default
  3. commonJs模块化导入: require
  4. commonjs模块化导出: module.exports module

箭头函数和普通函数的区别

  1. 箭头函数this指向上下文,普通函数this看调用方式
  2. 剪头函数没有arguments对象,普通函数具备arguments对象
  3. 箭头函数没有prototype, 普通函数具备prototype
  4. 箭头函数不能用做构造函数,普通函数可以用做构造函数

对闭包是怎么理解的?

  • 基本形式:两个嵌套关系的函数,内部函数可以访问外部函数定义的局部变量,那么该变量与内部函数就构造了闭包的形式
  • 优点:形成私有空间,避免全局变量的污染
  • 缺点:持久化内存,导致内存泄露
  • 解决:
    • 1、尽快避免函数的嵌套,以及变量的引用
    • 2、执行完的变量,可以赋值null,触发垃圾回收机制,进行回收释放内存

描述下垃圾回收机制?

首先:垃圾回收机制内部算法:引用计数 和 标记清除

接下来:

  • 引用计数:把堆上对象能够访问次数记下来,如果发现某个对象计数为0,算法认为没有变量访问这个对象。该对象所占空间,判定是垃圾,进行回收!但是:如果两个对象相互引用,各自计数永远不会为0,不会判定为是垃圾,不会回收!所以:主流浏览器不再使用该算法!
  • 标记清除:核心就是 从 使用对象次数 到 无法到达对象;只要是堆上对象无法访问,哪怕是对象相互引用,但是无法访问,算法对该对象标记为垃圾空间!

什么是原型对象和原型链

答:

原型对象:每个构造函数都有prototype属性,这个属性的值是个对象,称之为原型对象!

原型链:对象都有__proto__属性,这个属性指向它的原型对象,原型对象也是对象,也有__proto__属性,指向原型对象的原型对象,这样一层一层形成的链式结构称为原型链.

原型链有什么意义?

总得来说:给实例化对象上调用方法或使用某个属性,提供查询机制!

具体查询:

先在实例化对象本身上去找该方法!

如果没有,去实例化对象的__proto__(原型对象上去找)

如果当前原型对象上还没有该方法,继续往原型对象上的原型对象上去找

如果还是没有找到,报错 对象.xxx is not function

你能说说怎么理解事件循环机制的? 

1、JavaScript 是一门单线程语言. 单线程可能会出现阻塞的情况,所js分了同步任务和异步任务。

2、同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 任务队列。

3、主线程内的任务执行完毕为空,会去 任务队列 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。

怎么理解面向对象

答:1、面向对象是一种软件开发的思想和面向过程是相对应的,就是把程序看作一个对象,将属性和方法封装其中,以提高代码的灵活性、复用性、可扩展性。
  2、面向对象有三大特性:封装、继承、多态。
       封装:把相关的信息(无论数据或方法)存储在对象中的能力
       继承:由另一个类(或多个类)得来类的属性和方法的能力
       多态:编写能以多种方法运行的函数或方法的能力
   3、js中对象是一个无序的数据集合或者也可以说是属性和方法的集合,可以动态的添加属性可方法。
   4、js是基于对象,但是也使用了嵌入了面向对象的思想,可以实现继承和封装,这样也可以提供代码的灵活性和复用性。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值