JS面试题收集(持续更新好中...)

1.JavaScript 中的垃圾回收机制

定义:指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。
JavaScript在创建对象时会为它们分配内存,不再使用时会自动释放内存,这个过程称为垃圾收集。

四种常见的内存泄漏:

  • 全局变量 不用var声明的变量,相当于挂载到window对象上,解决:使用严格模式
  • 未清除的定时器
  • 闭包
  • dom的引用:没有清理的dom元素引用

2.跨域解决方案

  1. (后端)服务器配置CORS(跨域资源共享)
  2. (后端)node.js或Nginx反向代理,把跨域改造成同域
  3. (前端)将JSON升级为JSONP在JSON基础上,利用 script 标签可以跨域的特性,加上头设置

3.事件传播的三个阶段

捕获 > 目标 > 冒泡

在捕获阶段,事件通过父元素向下传递到目标元素
然后到达目标元素,冒泡开始

4.JavaScript中作用域是指什么?

在JavaScript中,每个函数都有自己的作用域。
作用域基本上是变量以及如何通过名称访问这些变量的规则的集合。
只有函数汇总的代码才能访问函数作用域内的变量。

在同一个作用域中的变量名必须是唯一的。一个作用域可以嵌套在另一个作用域内。如果一个作用域嵌套在另一个作用域内,最内部作用域的代码可以访问另一个作用域的变量。

5.JavaScript中的null和undefined

  • null 表示一个空的对象,什么也没有
  • undefined 表示声明未赋值
  • undefined 是从null派生出来的
null == undefined  // true
null === undefined // false
typeof(null) // object
typeof(undefined) // undefined

6.什么是防抖和节流?有什么区别?如何实现?

防抖
触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算事件。
应用场景:

  • 搜索框输入查询
  • 表单验证
  • 按钮提交事件

思路:每次触发事件时都取消之前的延时调用方法

节流
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。
使用场景:

  • 按钮点击事件
  • 拖拽事件
  • onSroll

思路:每次触发事件时都判断当前是否有等待执行的延时函数

7.简述JavaScript原型、原型链?有什么特点?

原型:

  • 每一个构造函数都有一个 prototype 属性指向一个对象,这个对象就是构造函数实例的原型

原型链:

  • 每一个实例都有以__proto__属性执行原型对象,来获取原型对象上的属性和方法,原型对象中也有一个__proto__属性指向另外一个原型对象,以此类推,直到原型链的最终端null为止,这个串成链的过程就是原型链

特点:

  • 实现继承一个对象可以拿到另一个对象的属性和方法
  • 构造函数都有一个prototype属性指向原型对象
  • 原型对象都有一个constructor属性指向构造函数
  • 构造函数 new 实例化实例对象
  • 对象上有__proto属性指向原型

8.JS数据类型有哪些

8种数据类型:

  • 基本数据类型
    • string
    • number
    • boolean
    • undefined
    • null
    • symbol (ES6)
    • bigInt (ES6)
  • 引用数据类型
    • object

9.描述一下 cookies,sessionStorage 和 localStorage 的区别?

  1. cookie 是浏览器自动携带在请求里发送给服务端去验证的,sessionStorage 和 localStorage 不会自动携带
  2. cookie体积相对sessionStorage 和 localStorage 小
  3. 后端可以设置cookie之后,前端修改不了的
  4. cookie可以设置过期时间
  5. cookie是用来做状态保持的,因为http请求时无状态的
  6. cookie是用户第一次访问服务器服务器分发给浏览器的,第二次请求就会携带
  7. sessionStorage存储在内存中,关闭浏览器数据会消失
  8. localStorage 关闭浏览器数据不会消失,需要手动清除

10.介绍一下 XMLhttprequest 对象

Ajax 的核心是 JavaScript对象 XMLHttpRequest。该对象在 Internet Explorer5中首次引入,是一种支持异步请求的技术。通过XMLHttpRequest对选哪个,开发人员可以在页面加载以后进行页面的局部更新。

11.JS异步编程的几种方式及区别

  • js 是单线程语言
  • 所谓异步,就是指在执行一件任务,这件任务分A、B两个阶段,执行完A阶段后,需要去做另外一个任务得到结果后才能执行B阶段。
  • 异步编程有以下几种常用方式:callback、Promise、Generator、async。

1.callback
指通过函数传参传递到其他执行代码的,某一块可执行代码的引用,被主函数调用后又回到主函数
缺点:如果存在多个任务,需要层层嵌套,形成回调地狱,代码会显得冗余且耦合度很高。降低代码的阅读性和可维护性

2.promise
Promise是一个对象,可以获取异步操作的消息。
Promise对象有两个特点:

  • 对象的状态不受外界影响,Promise对象代表一个异步操作,有三种状态:pending,resolved和rejected
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果

常用于解决异步回调问题,可以将回调函数的嵌套改为链式调用。
优点:解决回调地狱
缺点:还是有些多余的代码,如被Promise包装的函数有一堆的new Promise、then、catch

3.generator函数
是ES6提供的一种异步解决方案,由每执行一次函数返回的是一个遍历器对象,返回的对象可以依次遍历Generator里面的每一个状态
需要用遍历器对象的next方法来执行函数

Generator有三个特征:

  • 函数命名时function后面需要加*
  • 函数内部有yield;外部执行需要调用next方法。
  • 每个yield会将跟在她后面的值包裹成一个对象的返回,
    返回的对象中包括返回值和函数运行状态,直到return,
    返回done为true。

优点:相比Promise在写法上更加精简且逻辑清晰

4.async
是Generator函数的语法糖
相比Generator函数,async函数在写法上的区别就是async替代了*,await替代了yield,并且async自带执行器

async函数返回的Promise,必须等到函数体内所有await后面的Promise对象都执行完毕后,或者return或者抛错之后才能改变状态;也就是只有async里面的异步操作全部操作完,才能回到主任务来,并且在then方法里面继续执行主任务。

async与Promise、Generator函数之间的对比

  • Promise虽然很好的解决了地狱回调的问题,但是代码中有很多与语义无关的then、
  • Generator函数需要自动执行器来执行函数,且yield后面只能是Promise对象或者Thunk函数。
  • async 函数的实现最简洁,最符合语义,几乎没有语义不相关的代码。与Generator相比不需要程序员再提供一个执行器,async本身自动执行,使用起来方便简洁。
// callback异步
function callback() {
    
    
  let readFile;
  readFile(fileA, function (data) {
    
    
    readFile(fileB, function (data) {
    
    
      // ......
    });
  });
}

// promise
function getData() {
    
    
  let require = new Promise((res, rej) => {
    
    
    res(), rej();
  });

  require
    .then((res) => {
    
    
      let result = res.data;
    })
    .catch((err) => {
    
    
      let error = err.message;
    });
}

// generator
function * foo(){
    
    
  yield getFirstData;
  yield getSecondData;
  return getThirdData
}

let require = foo()
require.next()
require.next()


// async
let getListData = async function(){
    
    
  let result = await reqGetListData()
  if(result.code = 200){
    
    
    // ...
  }
}

11.什么是闭包?为什么要用它?

闭包: 子函数调用父函数上的变量,返回给外界去使用,那么称子函数就是一个闭包

优点:缓存数据
缺点:内存泄漏,溢出
闭包作用:自执行函数,不会污染全局变量,形成块儿级作用域 变量私有化

猜你喜欢

转载自blog.csdn.net/qq_36842789/article/details/129555280