0


【javaScript面试题】2023前端最新版javaScript模块,高频24问

1d43f75f092a4050a8ce31e2d85f6868.gif

🥳博 主:初映CY的前说(前端领域)

🌞个人信条:想要变成得到,中间还有做到!

🤘本文核心:博主收集的关于javaScript的面试题

目录


一、2023javaScript面试题精选

1.js的数据类型

数据类型分为两种:基本数据类型与引用数据类型。基本数据类型有:number、string、boolean、null、undefined。引用数据类型有:array、function等(除了基本数据类型都是引用数据类型)

基本数据类型的主要特点是赋值方式是传值,并且值存在栈中。

引用数据类型的主要特点是赋值方式是传址,并且值存在堆中。


2.双等和三等的区别

双等主要是值类型进行比较,三等是值类型与数据类型进行双层比较。

简单来说就是三等因为传递的是地址,因此我们需要先对比数据类型,再看地址内部存储的数据是否相等。而双等仅仅是看值是否相等,值相等即可无需比较类型。


3.js中布尔值为false的六种情况

  1. undefined(未定义找不到值时出现)、
  2. null(代表空值)
  3. NaN(无法计算时候出现表示非数值,typeof(NaN)是number类型)
  4. false(布尔值的false,注意:‘false’的布尔值为true(''这是字符串))
  5. 0(数字)
  6. ‘’或者""(单双引号,注意中间有空格是true)

因此我举个例子:true+true=2

0e21140f962c49b1b6d14ffe5212faea.png

4.let const var 区别

var:存在变量提升,可以先去声明再去使用,一个变量可多次声明,后面的声明会覆盖前面的声明

45469c1f7ef14027b1984b1adddb348c.png

const:const声明一个只读的变量,声明后,值就不能改变(引用类型地址不变即可值可改变)

02104d0cc486427789ad76c2eaed6f90.png

let:不存在变量提升,let声明变量前,该变量不能使用

8ad07a9a7b01454f9df9978f27f5ad18.png


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

写法不同。箭头函数更加专注于结果写法由于()=>{}构成,写法简洁

this指向不同。箭头函数中 this 的指向不同:在普通函数中,this 总是指向调用它的对象,如果用作构造函数,它指向创建的对象实例。箭头函数中没有this,箭头函数的this指向取决于外层作用域中的this,外层作用域或函数的this指向谁,箭头函数中的this便指向谁。

6.数组有哪些方法

大家可以看看这一篇文章:http://t.csdn.cn/v6Zqu

数组的增删改查操作:

push()、unshift、shift()、pop()、splice()、join()、reverse()

数组的遍历操作:

map()、filter()、some()、every()、findindex()、reduce()


7.map()对比forEach()

1.map有返回值,可以开辟新空间,return出来一个length和原数组一致的数组,即便数组元素是undefined或者是null。
2.forEach默认无返回值,返回结果为undefined,可以通过在函数体内部使用索引修改数组元素。
3.map的处理速度比forEach快,而且返回一个新的数组,方便链式调用其他数组新方法


8.for in 对比 for of区别

简单来说就是它们两者都可以用于遍历,不过for in遍历的是数组的索引(index),而for of遍历的是数组元素值(item)

a1b985d5054c44a2baa8deef1fa7e469.png

9.扁平化数组代码实现

①使用isArray()(检测是否是数组)配合concat()(合并数组)实现

②使用reduce配合isArrayy于concat遍历实现

③利用展开运算符的妙用

该三种方法的是来源于http://t.csdn.cn/s3CxR,博主:从人到猿

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
// isArray判断是不是数组
const a = [1, [2, [3, [4, 5]]]];
//   const flatten = (arr) => {
//     let result = [];
//     for (let i = 0; i < arr.length; i++) {
//       if (Array.isArray(arr[i])) {
//         result = result.concat(flatten(arr[i]));
//       } else {
//         result.push(arr[i]);
//       }
//     }
//     return result;
//   };
//   console.log(flatten(a));

// concat连接两个数组
// var sedan = ["S60", "S90"];
// var SUV = ["XC40", "XC60", "XC90"];

// var Volvo = sedan.concat(SUV);//['S60', 'S90', 'XC40', 'XC60', 'XC90']
// console.log(Volvo)

// const flatten = (arr) => {
//     return arr.reduce((prev,next)=>{
//       return prev.concat(Array.isArray(next)?flatten(next):next)
//     },[]);
//   };
//   console.log(flatten(a));

console.log(...a,'a');
//展开运算符配合concat
const flatten = (arr) => {
    while(arr.some(item=>Array.isArray(item))){
      arr = [].concat(...arr);
    }
    return arr;
  };
  console.log(flatten(a));

  </script>
</body>
</html>

10.数组去重的方法

该三种方法的是来源于http://t.csdn.cn/F3jkN,博主:经海路大白狗

1.利用新旧数组遍历对比法

arr=[1,5,1,3,5,4,3,9,8]

let newArr = [];
 /*   
    indexOf用于查找数组元素第一次出现的位置,没找到则返回值为-1,参数有两个,第一个为元素项目,参数二(可选)需要查找的位置,负数从-1往前面加 
 */
for (let i=0;i<arr.length;i++) {
    if (newArr.indexOf(arr[i]) === -1) {
        newArr.push(arr[i]);
    }
  }
console.log(newArr);//[1, 5, 3, 4, 9, 8]

2.利用新语法 new Set()

arr=[1,5,1,3,5,4,3,9,8]
let mySet = new Set(arr); // 非重复的类数组
console.log(mySet,'mySet');//{{1, 5, 3, 4, 9,8}
// let newArr = Array.from(mySet); // set转数组
let newArr = [...mySet]; // 或者是这种解构方法
console.log(newArr);//[1, 5, 3, 4, 9, 8]

3.filter与indexOf结合

/* 这个过滤就很巧妙,利用索引与每一项出现的首次位置(indexOf作用)进行对比,
  当符合条件的时候返回出去
 */ 
arr=[1,5,1,3,5,4,3,9,8]
var newArr = arr.filter((item, index) => {
    return arr.indexOf(item) === index;
})
console.log(newArr);//[1, 5, 3, 4, 9, 8]

4.includes()的妙用

arr=[1,5,1,3,5,4,3,9,8]
let newArr = [];
for (let i=0;i<arr.length;i++) {
    if (!newArr.includes(arr[i])) {
        newArr.push(arr[i]);
    }
}
console.log(newArr);//[1, 5, 3, 4, 9, 8]

5.利用对象属性来进行判断

arr=[1,5,1,3,5,4,3,9,8]
let obj = {}; // 对象的key值是唯一的
let newArr = [];
for (let i=0;i<arr.length;i++) {
    if (!obj[arr[i]]) {
        obj[arr[i]] = arr[i];
    }
}
console.log(obj)//{1: 1, 3: 3, 4: 4, 5: 5, 8: 8, 9: 9}

0708a7f7a2554f34bfcd91c963ba7ad3.png


11.防抖和节流

本知识点来源:http://t.csdn.cn/dwVOq,博主:留着鼻涕敲代码

防抖:多次触发只执行最后一次

应用场景:search搜索时,用户在不断输入值时,用防抖来节约请求资源

节流:规定时间内 只触发一次

应用场景:

1.鼠标不断点击触发,mousedown(单位时间内只触发一次)
2.监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

12.事件循环机制

事件循环理论先执行同步任务,再去执行我们的异步任务(先执行微任务再执行宏任务)。

异步任务进一步划分分为:

宏任务:script标签、setTimeout()、setInterval

微任务:Promise.then、nextTick

13.原型与原型链

  • 原型是我们创建函数的时候,系统帮我们自动生成的一个对象。 主要作用是解决构造函数内部方法内存资源浪费问题。在开发中我们一般把实例对象一些通用的方法放入原型中,在 vue 里面有时候也会给 vue 的原型添加一些公共类方法来实现所有的组件中可以共享成员。像一些常见的$router和$store 都是挂载到 vue 的原型上的。
  • 原型链是 js 对象一种查找机制,遵循就近原则。当我们访问一个对象中的成员的时候,会优先访问自己的,如果自己没有就访问原型的,如果原型也没有就会访问原型的原型,直到原型链的终点 null. 如果还没有,此时属性就会获取 undefined,方法就会报错 xxx is not a function。一般原型链主要是用来实现面向对象继承的。

14.localStorage、sessionStorage、cookie区别

共同点:都是保存在浏览器端

区别:l

①ocalStorage、sessionStorage不会自动把数据发送给服务器仅在本地存储

②cookie数据有路径(path)概念,可以固定存储到某个路径下

③cookie每次http请求都会携带,因此cookie只适合存储小数据,最大为4K左右,其他两者为5M

④有效期不同:cookie与localStorage都在过期前有效,但是sessionStorage在关闭的时候失效

⑤localStorage、cookie在同源窗口下共享数据,sessionStorage不在不同窗口下共享


15.判断数据类型的方式以及区别 (typeof instanceof 他们两者的区别)

1.typeof:一般判断基本数据类型

2.instanceof :一般判断引用类型数据,主要的作用就是判断一个实例是否属于某种类型,或者判断一个实例是否有它的原型。


16.null typeof为什么是一个object

因为在javaScript中,不同的对象都是使用二进制存储的,如果二进制前三位都是0的话,系统会判断为是Object类型,而null的二进制全是0,自然也就判断为Object


17.事件冒泡与事件捕获原理

事件捕获:触及的事件从文档根节点(Document 对象)流向目标节点,途中会经过目标节点的各个节点,并在这些节点上触发捕获事件,直至到达事件的目标节点。是由外到内层

事件冒泡:与事件捕获相反,事件会从目标节点流向文档根节点,途中会经过目标节点的各个父级节点,并在这些节点上触发捕获事件,直至到达文档的根节点。由内到外

a993fb0955aa4de482da1abd86f168d1.png


18.父div和子div都绑定了click事件,点击子div触发事件,这个事件的回调顺序

该原理同上,默认是事件冒泡,先触发子元素再往它的上级触发


19.阻止冒泡的方式及作用

使用 e.stopPropagation()来阻止事件冒泡。作用当然是阻止我们触发它上级的事件啦

74893300a3e84867ab278c60e5546169.png


20.事件委托的理解

js事件代理是把事件处理任务添加到上一级的元素中,这样就避免了把事件添加到多个子集元素上,底层原理是利用了事件冒泡机制

优点:

  • 减少注册时间,节约内存
  • 在table上代理所有td的click事件
  • 在ul上代理所有的click事件
  • 简化dom节点更新,相应事件的更新
  • 不需要在新添加的li上绑定click事件
  • 当删除某个li的时候不需要移除绑定在上面的click事件

缺点:

  • 对于不冒泡的事件不给予支持
  • 层级太多肯能会被中间的某层阻止掉
  • 理论上会导致浏览器会频繁的调用处理函数,虽然可能不需要处理

21.call、apply、bind的区别

本知识点来源:http://t.csdn.cn/3UPti,博主:dream_reason

共同点:

  • 都是用来改变函数的this对象的指向的
  • 第一个参数都是this要指向的对象
  • 都可以参加后续参数传参

不同点:

  • bind是返回对应函数,便于稍后调用;apply、call则是立即调用
  • apply和call功能一样,只是传入的参数列表形式不同,其中 thisArg 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

22.js闭包

一个作用域可以访问另外一个函数内部的局部变量,或者说一个函数(子函数)访问另一个函数(父函数)中的变量。此时就有闭包产生,那么这个变量所在的函数我们就称之为闭包函数。

优缺点:闭包的主要作用是延伸了变量的作用范围,因为闭包函数中的局部变量不会等着闭包函数执行完成就销毁,因为还有别的函数需要调用它,只有等这所有的函数都调用完了它才会被销毁。

如何解决:用完之后手动释放。


23.内存泄漏怎么理解

内存泄漏指的是我们用动态存储分配的函数来开辟空间,但是在使用完了没有释放,结果就一直占据该内存单元,直到程序结束。简而言之就是用完了还没回收这就是内存泄漏。


24.哪些操作会造成内存泄露

  • 我们的setTimeout第一个参数是字符串而不是函数的时候
  • 闭包、控制台日志、循环(在两个对象彼此引用且彼此保留的时候就会产生循环)
  • 一个对象的引用数量为0,或者唯一作用就是循环引用(开辟空间没有用上)

至此本文结束,如对您有帮助请务必关注博主呦,万分感谢!!!


本文转载自: https://blog.csdn.net/m0_61118311/article/details/129293568
版权归原作者 初映CY的前说 所有, 如有侵权,请联系我们删除。

“【javaScript面试题】2023前端最新版javaScript模块,高频24问”的评论:

还没有评论