前端高频JS面试题(附答案+视频讲解)

news2024/12/26 4:02:12

高频前端js面试题总结 对应的视频讲解位置

2023前端高频面试题-JS高频面试题(上)_哔哩哔哩_bilibili

目录

1. var let const 的区别?

2. javascript 有哪些基础数据类型?

3. null和undefined区别

4. == 与 === 的区别?

5. js中那些数据在 if 判断时是 false

6. 判断数据类型的方法有哪些,有什么区别

7. JS垃圾回收

8. this指向

9. call、apply、bind

10. 闭包、闭包的使用场景

11. 什么是事件代理/事件委托?

12. 如何阻止事件冒泡?

13. new操作符的实现原理

14. 回流与重绘

15. Javascript原型链

16. 深拷贝浅拷贝

17. 数组去重

18. 数组的方法

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

20. forEach和map方法有什么区别

21. for...in和for...of的区别


1. var let const 的区别?

  1. const 定义常量, 不可以重复赋值    块级作用域   不存在变量提升
  1. var 定义变量,可以重复声明  var 全局作用域或函数作用域    有变量提升
  2. let 定义变量,不可以重复声明 , 块级作用域   不存在变量提升

2. javascript 有哪些基础数据类型?

  • 基础数据类型String、Number、Boolean、Undefined、Null
  • 引用数据类型: Object、Array、Function、Date等
  • Symbol、BigInt是ES6之后新增的 属于基本数据类型
    • Symbol

指的是独一无二的值

    • BigInt

是一种数字类型的数据,它可以表示任意精度格式的整数

3. null和undefined区别

  • 首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。
  • undefined 代表的含义是

未定义,一般变量声明了但还没有定义的时候会返回 undefined

  • null 代表的含义是

空对象。null主要用于赋值给一些可能会返回对象的变量,作为初始化。

4. == 与 === 的区别?

  1. 双等号(==)进行相等判断时,如果两边的类型不一致,会强制类型转化再进行比较。
  2. 三等号(===)进行相等判断时,如果两边的类型不一致,不强制类型准换,直接返回 false

Object.is()

[]==[]

5. js中那些数据在 if 判断时是 false

  • 0、“”、false、null、undefined、NaN 判断为false (6个)
  • 其他皆为true

[]==false 和 ![]==false true

第一个 []==false 转为数字 0==0

第二个 ![]==false 转为布尔 false==false

[]==[] -- >false

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

下面6种值转化为布尔值时为false,其他转化都为true

1、undefined(未定义,找不到值时出现)

2、null(代表空值)

3、false(布尔值的false,字符串"false"布尔值为true)

4、0(数字0,字符串"0"布尔值为true)

5、NaN(无法计算结果时出现,表示"非数值";但是typeof NaN===“number”)

6、""(双引号)或’’(单引号) (空字符串,中间有空格时也是true)

注意空数组空对象,负值转的布尔值时都为true

6. 判断数据类型的方法有哪些,有什么区别

判断数据类型的方法

描述

typeof

判断基础数据类型(数组、对象、null都会被判断为object)

instanceof

判断引用数据类型,不能判断基本数据类型

constructor

判断数据的类型

Object.prototype.toString.call()

使用 Object 对象的原型方法 toString 来判断数据类型

 JavaScript类型判断的四种方法

一、typeof

typeof是一个操作符而不是函数,其右侧跟一个一元表达式,并返回这个表达式的数据类型。

返回的结果用该类型的字符串(全小写字母)

用于判断数据类型,返回值为6个[字符串],分别为string、Boolean、number、function、object、undefined。

console.log(typeof undefined) // undefind
console.log(typeof null)   // object
console.log(typeof true)   // boolean
console.log(typeof 43)    // number
console.log(typeof '21')   // string
console.log(typeof {a:1})   // object
console.log(typeof Symbol()) // symbol
console.log(typeof 123n)   // bigint
function a() {}
console.log(typeof a)     // function
var date = new Date()
var error = new Error()
console.log(typeof date)   // object
console.log(typeof error)   // object
​

二、instanceof

instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型

instanceof用来判断对象,代码形式为obj1 instanceof obj2(obj1是否是obj2的实例),obj2必须为对象,否则会报错!其返回值为布尔值

通俗一些讲,instanceof 用来比较一个对象是否为某一个构造函数的实例。注意,instanceof可以准确的判断复杂数据类型,但是不能正确判断基本数据类型

console.log(12 instanceof Number) // false
console.log('22' instanceof String) // false
console.log(true instanceof Boolean) // false
console.log(null instanceof Object) // false
console.log(undefined instanceof Object) // false
console.log([] instanceof Array)  // true
console.log({a: 1} instanceof Object) // true
console.log(json instanceof Object) // true
function a() { }
console.log(a instanceof Function) // true
console.log(new Date() instanceof Date) //true
let reg=new RegExp()
console.log(reg instanceof RegExp) //true
let error=new Error()
console.log(error instanceof Error) // true

三、Object.prototype.toString.call()

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

console.log(Object.prototype.toString.call(1))     // [object Number]
console.log(Object.prototype.toString.call(1n))     // [object BigInt]
console.log(Object.prototype.toString.call('123'))   // [object String]
console.log(Object.prototype.toString.call(true))    // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null))    // [object Null]
console.log(Object.prototype.toString.call({}))     // [object Object]
console.log(Object.prototype.toString.call([]))     // [object Array]
console.log(Object.prototype.toString.call(function a() {})) // [object Function]
console.log(Object.prototype.toString.call(Symbol()))     // [object Symbol]
console.log(Object.prototype.toString.call(Math))       // [object Math]
console.log(Object.prototype.toString.call(JSON))       // [object JSON]
console.log(Object.prototype.toString.call(new Date()))    // [object Date]
console.log(Object.prototype.toString.call(new RegExp()))   // [object RegExp]
console.log(Object.prototype.toString.call(new Error))    // [object Error]
console.log(Object.prototype.toString.call(window)      // [object Window]
console.log(Object.prototype.toString.call(document)     // [object HTMLD

四、constructor

constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的。 constructor属性表示原型对象与构造函数之间的关联关系,如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,一般要同时修改constructor属性的指向。

constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的。
constructor属性表示原型对象与构造函数之间的关联关系,如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,一般要同时修改constructor属性的指向。
console.log('22'.constructor === String)       // true
console.log(true.constructor === Boolean)      // true
console.log([].constructor === Array)        // true
console.log(document.constructor === HTMLDocument)  // true
console.log(window.constructor === Window)      // true
console.log(new Number(22).constructor === Number)  // true
console.log(new Function().constructor === Function) // true
console.log((new Date()).constructor === Date)    // true
console.log(new RegExp().constructor === RegExp)   // true
console.log(new Error().constructor === Error)    // true

注意:

1、null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。

2、函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object

7. JS垃圾回收

有两种垃圾回收策略:

  1. 标记清除:

标记阶段即为所有活动对象做上标记,清除阶段则把没有标记(也就是非活动对象)销毁。

  1. 引用计数:

它把对象是否不再需要简化定义为对象:有没有其他对象引用到它。如果没有引用指向该对象(引用计数为 0),对象将被垃圾回收机制回收。

8. this指向

9. call、apply、bind

三者区别

  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果没有这个参数或参数为undefined或null,则默认指向全局window
  • 三者都可以传参,
    • call是参数列表,apply是数组,call和apply是一次性传入参数,
    • bind是参数列表,但可以分为多次传入参数
  • bind是返回绑定this之后的函数,apply、call 则是立即执行

应用场景

  1. call 经常做继承。
  2. apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。
  3. bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。

10. 闭包、闭包的使用场景

闭包的概念:

闭包:是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。

闭包的特性

1.函数内再嵌套函数 2.内部函数可以引用外层的参数和变量 3.参数和变量不会被垃圾回收机制回收

闭包的优缺点

  • 优点:延长变量生命周期、私有化变量
  • 缺点:过多的闭包可能会导致内存泄漏

闭包的应用场景

  • ajax请求的成功回调
  • 事件绑定的回调方法
  • setTimeout的延时回调
  • 函数内部返回另一个匿名函数
  • 函数节流、防抖 封装模块

11. 什么是事件代理/事件委托?

事件代理/事件委托是利用事件冒泡的特性,将本应该绑定在多个元素上的事件绑定在他们的祖先元素上,尤其在动态添加子元素的时候,可以非常方便的提高程序性能,减小内存空间。

12. 如何阻止事件冒泡?

w3c的方法是e.stopPropagation(),

e.stopPropagation();

如何阻止默认事件?

w3c的方法是e.preventDefault()

function stopDefault( e ) { e.preventDefault(); }

13. new操作符的实现原理

  1. 首先创建了一个新的空对象
  2. 设置原型,将对象的原型设置为函数的 prototype 对象。
  3. 让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性)
  4. 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

14. 回流与重绘

当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树。完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘

15. Javascript原型链

首先理解三个概念:

  • prototype:原型对象,每个函数都有一个 prototype 属性,再通过 new 命令实例对象时,该属性会成为该实例的原型对象。
  • constructor:构造函数。指向原型对象的 constructor
  • __proto__:实例对象的原型

在javascript中,实例对象与原型之间的链接,叫做原型链。Javascript解析引擎在读取一个Object的属性的值时,会沿着原型链向上寻找,如果最终没有找到,则该属性值为undefined;如果最终找到该属性的值,则返回结果。

16. 深拷贝浅拷贝

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

浅拷贝

// 第一层为深拷贝 Object.assign() Array.prototype.slice() //扩展运算符 ...

深拷贝

JSON.parse(JSON.stringify())

递归函数

let obj = {
    a: 'hello',
    b: [10, 20],
    c: { name: 'admin',age:{xx:''} }
}

//定义函数实现深层拷贝
function deepCopy(obj) {
    //1. 先判断obj是否存在 是否是对象格式 
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }
    //2. 创建一个新的容器存储拷贝的数据 
    let newObj = Array.isArray(obj) ? [] : {};
    //3. 遍历对象for循环可以 获取所有的下标keys 
    let temp=null;// temp键值
    //遍历下标 --获取元素的值
    for(let key in obj){
        temp=obj[key];//键值
        //获取键值 存储新的容器里--需要判断当前的键值的类型是不是对象 
        if(temp && typeof temp ==='object'){
            newObj[key]=deepCopy(temp)
            //newObject={a:hello,b}
        }else{
            //键值是基本数据类型可以直接存储
            newObj[key]=temp;
        }
    }
    return newObj;
}

let obj2=deepCopy(obj)

17. 数组去重

  1. 使用es6 set方法

[...new Set(arr)]

let arr = [1,2,3,4,3,2,3,4,6,7,6]; let unique =(arr)=>[...newSet(arr); unique(arr);//[1,2,3,4,6,7]

  1. 利用新数组indexOf查找indexOf()方法可返回某个指定的元素在数组中首次出现的位置。如果没有就返回-1。
  2. for双重循环通过判断第二层循环,去重的数组中是否含有该元素,如果有就退出第二层循环,如果没有j==result.length就相等,然后把对应的元素添加到最后的数组里面。

18. 数组的方法

数组的方法

描述

map

遍历数组,返回回调返回值组成的新数组

forEach

无法break,可以用try/catch中throw new Error来停止

filter

过滤

some

有一项返回true,则整体为`true

every

有一项返回false,则整体为`false

join

通过指定连接符生成字符串

push / pop

末尾推入和弹出,改变原数组。push 返回数组长度, pop 返回原数组最后一项;

unshift / shift

头部推入和弹出,改变原数组,unshift 返回数组长度,shift 返回原数组第一项 ;

sort(fn) / reverse

排序与反转,改变原数组

concat

连接数组,不影响原数组, 浅拷贝

slice(start, end)

返回截断后的新数组,不改变原数组

splice(start, number, value...)

返回删除元素组成的数组,value 为插入项,改变原数组

indexOf / lastIndexOf(value, fromIndex)

查找数组项,返回对应的下标

reduce / reduceRight(fn(prev, cur), defaultPrev)

两两执行,prev 为上次化简函数的return值,cur 为当前值 当传入 defaultPrev 时,从第一项开始; 当未传入时,则为第二项

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

  1. 箭头函数比普通函数更加简洁
  2. 箭头函数没有自己的this
  3. 箭头函数继承来的this指向永远不会改变
  4. 箭头函数不能作为构造函数使用
  5. 箭头函数没有自己的arguments
  6. 箭头函数没有prototype
  7. call()、apply()、bind()等方法不能改变箭头函数中this的指向

20. forEach和map方法有什么区别

  • forEach()方法会针对每一个元素执行提供的函数,对数据的操作会改变原数组,该方法没有返回值;
  • map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值;

注意:

  •  forEach()会改变原数组的方法
  • 参数:item数组中的当前项,index当前项的索引,array原始数组;
  • 数组中有几项,那么传递进去的匿名回调函数就需要执行几次

使用场景:当我们对数组的元素进行处理时(例如:增加元素,元素值改变),可以使用这个函数

注意:

item数组中的当前项,index当前项的索引,array原始数组

map的回调函数中支持return返回值,return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆了一份,把克隆这一份的数组中的对应项改变了 );

map会改变原数组的方法,

map的执行速度更快,比forEach的执行速度快了70%;

使用场景:

map适用于你要改变数据值的时候,不仅在于它更快,而且返回一个新的数组,这样可以提高复用性(map(),filter(),reduce())等组合使用。

var arr = [1, 2, 3, 4, 5]; var newArr = arr.map(num => num * 2).filter(num => num > 5); // newArr = [6, 8, 10]

总结:

  1. 能用forEach()做到的,map()同样可以。反之亦成立
  2. map()会分配内存空间存储新数组并返回,forEach()不会返回数组
  3. forEach()允许callback更改原始数组的元素。而map()返回新的数组

21. for...in和for...of的区别

  • for…of 遍历获取的是对象的键值,for…in 获取的是对象的键名;
  • for… in 会遍历对象的整个原型链,性能非常差不推荐使用,而 for … of 只遍历当前对象不会遍历原型链;
  • 对于数组的遍历,for…in 会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for…of 只返回数组的下标对应的属性值;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/682540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二十三种设计模式第十二篇--组合模式

组合模式是一种结构型设计模式,它允许将对象组合成树形结构来表示整体-部分的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 在组合模式中,有两种类型的对象:叶子对象和组合对象。叶子对象表示树结构中的叶子节点&…

为什么需要建设海绵城市?

海绵城市,是新一代城市雨洪管理概念,是指城市在适应环境变化和应对雨水带来的自然灾害等方面具有良好的“弹性”,也可称之为“水弹性城市”。其本质上是一种生态化的城市发展模式,其核心是将城市建设与生态环境保护相结合。 为什么…

二.《UE4奥丁》解密哈希ID

哈希表概念 1.相信大家经常在UE4或者UE5游戏逆向中遇到下面的代码段 $ > > 41:8B42 0C > mov eax,dword ptr ds:[r10C] > $4 > 3B05 AE589B04 > cmp eax,dword ptr ds:[7FF7B68B74F4] …

DeFi(去中心化金融),定义金融服务的未来

在数字化时代,区块链技术的发展引领了金融服务的全新变革。去中心化金融(DeFi)作为区块链技术的重要应用之一,正在重新定义传统金融服务的未来。本文将探讨DeFi的概念、优势以及对金融服务的影响,并展望其在未来的发展…

Linux上配置安装Nginx

Linux上安装配置Nginx 前言安装参考 前言 在前文中介绍了Nginx:Nginx入门 现在我们来试着在服务器上安装以下Nginx,以下操作使用的版本为1.20.0 下载地址为:Nginx官网下载地址 安装 先把包丢上去,我这里使用的是XFtp连接的服…

【Spring】— Spring MVC简单数据绑定(二)

接上文:【Spring】— Spring MVC简单数据绑定(一) 目录 2.3绑定POJO类型 2.3绑定POJO类型 在使用简单数据类型绑定时,可以很容易地根据具体需求来定义方法中的形参类型和个数,然而在实际应用中,客户端请求…

java学习记录之MySql二

1 mysql回顾 1.1 DDL 数据定义语言:结构  数据库database create database 数据库名称 character set 字符集 [collate 比较]; drop database 数据库名称; alter database 数据库名称 character set 字符集 …;  表 create table 表名(字段描述 , … ); 字段描述…

优雅地在高版本Android将文件保存到磁盘

Android对于文件存储的限制正在日趋严格。事实上,从Android 11(Android R)开始,那些传统的文件保存和读取方式统统失效了。 而高版本Android中存/取文件操作,百度到的内容是可行的,但是非常麻烦&#xff0c…

AIGC时代,基于云原生 MLOps 构建属于你的大模型(下)

为了满足企业在数字化转型过程中对更新迭代生产力工具的需求,灵雀云近日推出了Alauda MLOps 解决方案,帮助企业快速落地AI技术、实现智能化应用和服务。 AIGC大模型已成为企业创新引擎 随着ChatGPT的爆火,越来越多的人考虑使用AI来提升我们日…

python机器学习——回归模型评估方法 回归算法(线性回归、L2岭回归)

目录 回归模型评价方法【回归】线性回归模型1.线性模型2.线性回归3.损失函数(误差大小)4.解决方法1) 最小二乘法之正规方程2) 最小二乘法之梯度下降 5.代码实现5.模型保存与加载6.特点 实例:波士顿房价【回归】带有L2正则化的岭回归 回归模型…

C++初阶之类和对象(上)

类和对象(上) 1、面向过程和面向对象初步认识2、类的引入3、类的定义4、类的访问限定符及封装4.1 访问限定符4.2 封装 5、类的作用域6、类的实例化7、类对象模型7.1 如何计算类对象的大小 8.this指针8.1 this指针的引出8.2 this指针的特性8.3. C语言和C实…

Python开发工具PyCharm 2023.1发布,这些新功能都值得期待!

PyCharm 2023.1 现已正式发布!今年的第一个主要版本带来了对远程Jupyter Notebook的支持、对新UI的增强、改进的泛型类型推断等。 JetBrains PyCharm是一种Python IDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外&#xff0…

SpringBoot 使用 Testcontainers 进行容器化集成测试

SpringBoot 使用 Testcontainers 进行容器化集成测试 容器化集成测试是测试应用程序与其依赖项之间的集成,其中依赖项以容器的形式运行。SpringBoot提供了Testcontainers来测试应用程序与依赖项之间的集成,本文将介绍如何使用Testcontainers进行容器化集…

详细解说一次性低代码和持续化低代码的关键区别在哪里

为什么很多开发团队吐槽低代码开发平台,其中大致归结了几个方面的原因: 1、使用过后会降低对技术的依赖度,工具人的倾向更加严重 2、目前大部分的低代码都是一次性的低代码,仅仅是在第一次构建模型的时候,可以生成一…

CDC介绍

CDC介绍 1 CDC Change Data Capture:定义了一种场景,即识别并捕获数据库表中数据的变更,并交付给下游进一步处理。CDC是对针对行级数据记录的。其中数据的变更信息,即 CDC 的数据结构,包括变更是什么样的操作&#x…

《JDK8特性深入讲解》学习笔记

Lambda表达式 如果不适用lambda表达式的话,可以使用匿名内部类,但是代码会显得有点多 lambda表达式其实就是匿名内部类 Lambda表达式简化了匿名内部类的使用,语法更加简单。 语法规则 (参数类型 参数名称) -> {代码体; } Lambda表达…

Unreal 5 实现Data Table 数据表格的使用

数据是一个游戏重要的组成部分,按分工,数据会交由策划去配置,所以,你的数据不可能直接写到蓝图里面,而是有一个专门的数据表格去配置。 大家通用的方式是策划在Excel内编辑完成,然后通过工具生成游戏需要使…

RabbitMQ安装以及SpringBoot整合RabbitMQ

SpringBootMQ整合Rabbit RabbitMQ安装以及SpringBoot整合 1、Docker安装RabbitMQ #拉取rabbitmq镜像 docker pull rabbitmq#启动RabbitMQ docker run -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq#安装图形化插件 #进入容器 docker exec -i…

ubantu16.04搭建Qt环境

目录 ubantu16.04搭建Qt环境 下载opensource 安装qmake 安装g以及依赖库 配置环境 编译原码 安装make 查看qmake是否安装 配置环境变量 qmake编译c/c代码 安装qtcreator Linux编译Qt代码 ubantu16.04搭建Qt环境 下载opensource 「下载 qt-everywhere-opensource-s…

用于配电室的内部环境监控系统设计与产品选型

摘要:配电室是配电系统的重要组成部分,影响着电力用户的用电需求,需要保障其安全、可靠运行。针对配电室内部环境进行了深入分析,设计了一种内部环境监控系统。通过该系统可以采集配电室内部的温度、湿度、液位、SF6气体和烟雾&am…