面试必备!js高频面试题

发布于:2022-12-05 ⋅ 阅读:(275) ⋅ 点赞:(0)

 

1. 闭包

1.1 什么是闭包

内部函数引用外部函数变量的集合

闭包 = 内部函数 + 外部变量


 

1.2 闭包的应用场景

节流和防抖 实现数据的私有化

1.3 闭包滥用会造成什么问题

内存泄漏


 

2. 垃圾回收策略有哪两种方式

  1. 引用计数法(已被淘汰)

  2. 标记清除法


 

3. 什么是作用域链

本质是底层的变量查找机制

查找规则:

  1. 优先在当前作用域中查找

  2. 如果当前作用域中找不到这个变量,则依次逐级查找父级作用域,直到全局作用域


 

4. 箭头函数的this指向

箭头函数本身并没有this,它只会从自己的上一层作用域沿用this


 

5. new一个对象的执行过程

  1. 先创建一个空对象

  2. this指向这个空对象

  3. 指向构造函数里的代码,给这个对象添加属性和方法

  4. 返回这个对象


 

6. 什么是原型

原型就是对象(原型对象)

  1. 所有的函数,都有一个prototype属性,属性值是一个指针,指向它的原型对象

  2. 通过构造函数创建的实例,都有一个__proto__属性,属性值也是一个指针,指向原型对象

  3. 原型对象上默认有一个constructor属性,指回它的构造函数


 

7. 谈一谈对原型链的理解

每个对象都能通过它的__proto__属性访问到它的原型对象,原型对象也有它的原型对象

当访问一个对象的属性和方法时,先在自身寻找,如果没有,就通过__proto__这条链,向上查找,一直找到最顶层Object.prototype为止


 

8. 什么是浅拷贝,什么是深拷贝

8.1 浅拷贝

在堆内存中新开辟一个空间存储对象,拷贝原对象第一层的基本数据类型的值和引用数据类型的地址

8.2 深拷贝

在堆内存中新开辟一个空间存储对象,递归的拷贝原对象的所有属性和方法


 

9. 实现浅拷贝的方式

  1. Object.assign()

  2. 扩展运算符 ...

  3. Array.prototype.concat()

  4. Array.prototype.slice()


 

10. 实现深拷贝的方式

  1. JSON.parse(JSON.stringify())

  2. 递归

  3. 使用一些JSlodash

10.1 JSON.parse(JSON.stringify())的缺陷

  1. 拷贝对象的值如果是function / undefined / Symbol , 这个键值对丢失

  2. 如果是正则(RegExp),会变成空对象

  3. 如果是infinity / NaN, 会变成null

  4. 如果是Date日期,会变成日期字符串


 

11. call, bind, apply区别

  1. 它们都能改变this指向

  2. call接收一个参数列表,apply接收一个数组

  3. callapply都会立即执行,bind会返回一个函数,需要手动调用

12 什么是防抖,什么是节流?手写?

12.1 防抖

当持续触发事件时,一定时间内没有触发事件,回调函数才会执行一次,如果设定延迟时间到来之前,事件又触发了,就重新计算延时

简答:你先抖一会,啥时候停了,再继续执行

手写:

const input = document.querySelector('input')
​
const sendMsg = function (x, y) {
  console.log('发送请求')
}
const debounce = (fn, ms = 100) => {
  let timerId
  return function (...arr) {
    clearTimeout(timerId)
    timerId = setTimeout(() => {
      fn.call(this, ...arr)
      // fn.apply(this,arr)
    }, ms)
  }
}
input.addEventListener('keyup', debounce(sendMsg, 500).bind(input, 1, 2))

12.2 节流

减少一段时间内,函数的执行频率

手写:

const box = document.querySelector('.box')
​
let i = 1
const mouseMove = () => {
  box.innerHTML = ++i
}
​
const throttle = (fn, ms = 100) => {
  let timerId
  return function (...arr) {
    if (timerId) return
    
    timerId = setTimeout(() => {
      fn.call(this, ...arr)
      
      timerId = null
    }, ms)
  }
}
​
box.addEventListener('mousemove', throttle(mouseMove, 1000))

 

13. 数据类型,堆栈存储, 检测数据类型的方式

13.1 基本数据类型 (7种)

1.Number 2.String 3.Boolean 4.null 5.undefined 6.Symbol 7.BigInt

基本数据类型将值存放在栈中

13.2 引用数据类型

Object ==> function / Array / Date / RegExp

引用数据类型在堆在存放数据,在栈中存放一个地址,指向堆中的地址

13.3 检测数据类型的方式

  1. 检测基本数据类型 typeof

  2. 检测引用数据类型 A instanceof B

  3. 既能检测基本数据类型,也能检测引用数据类型 Object.prototype.toString.call()

14. localStorage sessionStorage区别

1. 生命周期

localStorage的生命周期永久生效,除非手动删除,否则将页面关闭也依然存在

sessionStorage的数据随着页面的关闭而清除

2. 数据共享

localStorage的数据在同一浏览器,同一域名下,在多个页面也能共享

sessionStorage的数据在同一个页面下可以共享 (前提:同一个域名下)

15. 事件委托原理

利用事件冒泡,将事件监听绑定在父元素身上,通过父元素监听子元素

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到