前端面试——JavaScript面经(持续更新)
一、数据类型
1. JavaScript用哪些数据类型、它们有什么区别?
JavaScript共有八种数据类型,分别包括5种基本数据类型和3种非基本数据类型。
- 基本数据类型:
Undefined
、Null
、Boolean
、Number
、String
。 - 非基本数据类型:
Object
、Symbol
、BigInt
。
其中Symbol
和BigInt
是ES6新增的数据类型:
Symbol
代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题。BigInt
是一种数字类型的数据,它可以表示任意精度格式的整数,使用BigInt
可以安全地存储和大整数,即使这个数超出了Number的安全整数范围。
区别一:分为原始数据类型和引用数据类型。
- 原始数据类型:
Undefined
、Null
、Boolean
、Number
、String
。 - 引用数据类型:
Object
。另外还有数组Array
和函数Function
。
区别二:存储位置不同。
- 原始数据类型直接存储在**栈(stack)**中,往往占据空间小、大小固定、属于被频繁使用数据,所以放在栈中。
- 引用数据类型存储在**堆(heap)**中,往往占据空间大、大小不固定,如果存在栈中将会影响程序运行的性能。因此,引用数据类型在栈中存储了指针,指针指向堆中该实体的起始地址。当解释器寻找引用值时,会先检索其在栈中的地址,再根据地址从堆中获得实体。
扩展知识:堆与栈
堆和栈的概念存在于数据结构和操作系统内存中。
- 在数据结构中:
- 栈:先进后出
- 堆:先进先出
- 在操作系统中分为堆区和栈区:
- 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。操作方式类似于数据结构中的栈。
- 堆区内存一般由开发者分配释放,若开发者不释放,程序结束时可能由垃圾回收机制回收。
2. 数据类型的检测方式有哪些?详细讲讲
2.1 typeof
// 1.typeof 数组、对象和null都会被视为object 其他类型都判定正确
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof null); // object
console.log(typeof function () {}); // function
console.log(typeof 1); // number
console.log(typeof true); // boolean
console.log(typeof "str"); // string
console.log(typeof undefined); // undefined
console.log(typeof Symbol()); // symbol
console.log(typeof NaN) // number
根据上面的结果可以看到数组、对象和null都会被视为object,其他类型都能判定正确。
2.2 instanceof
它的原理是:判断在其原型链中能否找到该类型的原型
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log("str" instanceof String); // falseconsole.log([] instanceof Array); // true
console.log(function () {} instanceof Function); // true
console.log({} instanceof Object); // true
console.log(null instanceof Object); // false 这是因为null是原型链的尽头 它没有后续原型链 更不可能找到Object类型的原型
根据上面的结果可以看到 instanceof只能正确判断引用类型,基本数据类型无法判定。
需要注意的是:null instanceof Object结果是false
,因为null是原型链的尽头,它没有后续原型链,更不可能找到Object类型的原型。
2.3 constructor
它的原理是:**除了null之外,任何对象都会在其prototype
/__proto__
上有一个constructor
属性,而constructor属性返回一个引用,这个引用指向创建该对象的构造函数,而Number
、Boolean
、String
、Array
都属于构造函数。**因此通过construct和构造函数就能判断类型是否符合。
console.log((2).constructor); // ƒ Number() { [native code] } Number构造函数
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(("str").constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function () {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
// console.log((null).constructor === Object); // 会报错 原因是null不存在constructor
// console.log((undefined).constructor === Object); // 会报错 原因是undefined不存在constructor
// console.log((null).constructor); // 会报错
// console.log((undefined).constructor); // 会报错
从上面的结果看到,constructor
除了不能判断null
和undefined
外,其它类型都能判断。
需要注意的是,如果创建的对象的原型被改变了,constructor
就不能用来判断数据类型了。
function Fn() {}
console.log(Fn.prototype.constructor); // f Fn() {}
Fn.prototype = new Array()
console.log(Fn.prototype.constructor); // ƒ Array() { [native code] }
let f = new Fn();
console.log(f.constructor); // ƒ Array() { [native code] }
console.log(f.__proto__); // ƒ Array() { [native code] }
console.log(f.constructor === Fn); // false
console.log(f.constructor === Array); // true
扩展知识:constructor
的两个作用:
- 判断数据类型。
- 对象实例通过construct对象访问它的构造函数。
2.4 Object.prototype.toString.call()
它的原理是:对象原型上的toString
方法会获取当前对象的类型然后返回[object Type]
字符串,由于部分内置对象对toString
重写了,因此需要调用.call()
来利用原本的toString
函数,.call(args)
方法实现让调用call
方法的对象的this
指向传的参数args
。
let a = Object.prototype.toString;
console.log(a.call(2)); // [object Number]
console.log(a.call(2) == Number); // false
console.log(a.call(2) == "[object Number]"); // trueconsole.log(a.call(true)); // [object Boolean]
console.log(a.call(true) == Boolean); // false
console.log(a.call(true) == "[object Boolean]"); // trueconsole.log(a.call("str")); // [object String]
console.log(a.call("str") == String); // false
console.log(a.call("str") == "[object String]"); // trueconsole.log(a.call(new Date())); // [object Date]
console.log(a.call(new Date()) == Date); // false
console.log(a.call(new Date()) == "[object Date]"); // trueconsole.log(a.call([])); // [object Array]
console.log(a.call(function () {})); // [object function]
console.log(a.call({})); // [object Object]
console.log(a.call(undefined)); // [object undefined]
console.log(a.call(null)); // [object Null]
通过上面代码可以看到,Object.prototype.toString.call()
可以验证任何类型。
2.5 封装一个类型验证的方法
大型项目中往往会使用Object.prototype.toString.call()
封装一个isType
方法来验证类型,封装代码如下:
function isType(data, type) {const typeObj = {"[object String]": "string","[object Number]": "number","[object Boolean]": "boolean","[object Null]": "null","[object Undefined]": "undefined","[object Object]": "object","[object Array]": "array","[object Function]": "function","[object Date]": "date", // Object.prototype.toString.call(new Date())"[object RegExp]": "regExp","[object Map]": "map","[object Set]": "set","[object HTMLDivElement]": "dom", // document.querySelector('#app')"[object WeakMap]": "weakMap","[object Window]": "window", // Object.prototype.toString.call(window)"[object Error]": "error", // new Error('1')"[object Arguments]": "arguments",};let name = Object.prototype.toString.call(data); // 借用Object.prototype.toString()获取数据类型let typeName = typeObj[name] || "未知类型"; // 匹配数据类型return typeName === type; // 判断该数据类型是否为传入的类型
}
下面我们可以测试一下封装结果:
console.log(isType({}, "object"), // trueisType([], "array"), // trueisType(new Date(), "object"), // falseisType(new Date(), "date") // true
);
2.6 总结
方法名 | 效果 |
---|---|
typeof | 数组、对象和null 都会被视为object ,其他类型都能判定正确 |
instanceof | 只能正确判断引用类型,基本数据类型无法判定 |
constructor | 除了不能判断null 和undefined 外,其它类型都能判断 |
Object.prototype.toString.call() | 可以判断所有类型,但是返回结果是字符串【最推荐,封装isType 】 |
3. 判断数组的方式有哪些?
let arr = []
Object.prototype.toString.call(arr).slice(8,-1) === 'Array'
或者Object.protoType.toString.call(arr) === '[object Array]'
- 通过原型链判断:
arr.__proto__ === Array.prototype
- 通过
Array.isArray(arr)
- 通过
arr instanceof Array
4. null、undefined、Null有什么区别?
- 含义不同:
undefined
代表的含义是未定义,而null
代表的含义是空对象,NaN
表示不是一个数字,用于指出数字类型中的错误情况,通过执行数学运算没有成功时返回NaN
。。 - 初始化场景不同:通常变量声明了但还没有定义的时候使用
undefined
,null
主要用在初始化一些可能会返回对象的变量,NaN
不用于初始化。 - typeof判断结果不同:
typeof undefined
返回undefined
,typeof null
返回object
,typeof NaN
返回number
。
一般变量声明了但还没定义的时候会返回undefined
。
需要注意的是:
-
使用
null == undefined
返回true
,null === undefined
返回false
。 -
NaN
与自身不相等,NaN == NaN
和NaN === NaN
得到的结果都是false
。
5. 为什么0.1+0.2 !== 0.3,怎么才能让它们相等
大白话:
首先:因此js将数据转为二进制后处理数据【要点一】,0.1
转化为二进制为:0.0001 1001 1001 1001无限循环..
,0.2转化为二进制为:0.001 1001 1001 1001(无限循环)
。
又因为js的Number类型遵循IEEE754标准64位存储【要点二】,IEEE754标准64位内只有52位来表示小数,有很多小数转为二进制后存储无限位数,如果第53位为1的话,只保留52为就会进位【要点三】,从而导致精度丢失【第一次精度丢失】。
而后进行二进制相加的时候,也可能会存在进位的问题,进而导致精度丢失【第二次精度丢失】,最后相加得到的二进制结果转化为数字就会与我们平常相加得到的结果有偏差。
解决方法:
-
将两数转换为整数,在相加后转回小数
let x = (0.1 * 10 + 0.2 * 10) / 10 console.log(x === 0.3) // true
-
使用toFixed方法配合parseFloat方法
console.log(parseFloat((0.1 + 0.2).toFixed(1)) === 0.3) // true
-
根据真实结果减去预测结果是否小于
Number.EPSILON
在ES6中,提供了
Number.EPSILON
属性,它的值为2^-52
。console.log((0.1 + 0.2) - 0.3 < Number.EPSILON) // true
下面详细讲讲:
Number类型遵循的IEEE754 64位标准,也就是双精度浮点数(double)存储,它为每个数值分配64位存储空间,以科学计数法的方式存储。64位分配如下:1位符号位,11位指数位,剩余52位为小数位。
这里以0.1为例:
6. == 操作符的强制转换规则是怎么样的?
==
在比对双方类型不一样时,会进行类型转换。
其中包括:
- string转为number
- boolean转为number
- object转为字符串
[object Object]
判断流程如下:
- 先判断两者类型是否相同,同则比较大小
- 不同进行类型转换
- 先判断是否在比对
null
和undefined
,是的话返回true
- 接着按上述三个点的顺序类型转化
相关文章:

前端面试——JavaScript面经(持续更新)
一、数据类型 1. JavaScript用哪些数据类型、它们有什么区别? JavaScript共有八种数据类型,分别包括5种基本数据类型和3种非基本数据类型。 基本数据类型:Undefined、Null、Boolean、Number、String。非基本数据类型:Object、S…...

微前端——无界wujie
B站课程视频 课程视频 课程课件笔记: 1.微前端 2.无界 现有的微前端框架:iframe、qiankun、Micro-app(京东)、EMP(百度)、无届 前置 初始化 新建一个文件夹 1.通过npm i typescript -g安装ts 2.然后可…...

连锁便利店管理系统有什么用
连锁便利店管理系统对于连锁便利店的运营和管理非常有用。以下是一些常见的用途: 1. 库存管理:连锁便利店通常需要管理多个门店的库存,管理系统可以帮助实时掌握各个门店的库存情况,包括商品数量、进货记录、库存调拨等。这样可以…...

Vue 的两种实现:VSCode 中配置 vue 模板快捷方式的过程
1、创建配置文件: 其一、打开 VSCode ,CtrlShiftP, 打开搜索框: 其二、输入:user, 并点击进去 Snippets:Configure User Snippets 其三、输入 vue3js 并回车: 其四、打开项目,发现配置文件 vue3js.code-sn…...

electron 切换至esm
前言 好消息,经过不知道多少年的讨论。 electron28.0.0开始(23.08.31),默认支持esm了。 see https://github.com/electron/electron/issues/21457 使用方法 升级至electron^28.0.0简单地在package.json中添加"type":…...

【新版】软考 - 系统架构设计师(总结笔记)
个人总结学习笔记,仅供参考!!!! →点击 笔者主页,欢迎关注哦(互相学习,共同成长) 笔记目录 📢【系统架构设计系列】系统架构设计专业技能 计算机组成与结构操作系统信…...

Spring MVC 方法中添加参数、HttpServletRequest 和 HttpServletResponse 对象
在这个例子中,我们添加了 HttpServletRequest 和 HttpServletResponse 对象作为控制器方法的参数。这样,你就可以在方法内部同时访问请求参数、请求对象和响应对象,从而进行更灵活的 HTTP 请求和响应处理。 RestController public class MyC…...

单片机的RTC获取网络时间
理解网络同步校准RTC的原理需要考虑NTP、SNTP、RTC这三个关键组件的作用和交互。下面详细解释这个过程: 1. NTP(Network Time Protocol): 协议目的:NTP是用于同步计算机和设备时钟的协议。它通过在网络上与时间服务器通…...

Android 13 内置可卸载的搜狗输入法
环境 系统:Android 13 芯片厂商:展锐 需求 默认只有英文输入法,没有中文,需要中文输入法,且可以卸载的。 实测为搜狗输入法,百度等其它输入法也同样适用。 实现 在SDK目录中创建packages/apps/SogouIM…...

持续集成交付CICD:GitLabCI 封装Python类 并结合 ArgoCD 完成前端项目应用发布
目录 一、实验 1. 环境 2. Python代码实现获取文件 3.Python代码实现创建文件 4.Python代码实现更新文件 5.GitLab更新库文件与运行流水线 6.ArgoCD 完成前端项目应用发布 二、问题 1.Python获取GitLab指定仓库文件报错 2. K8S master节点运行Python代码报错 一、实验…...

第十三章 常用类(Math 类、Arrays 类、System类、Biglnteger 和BigDecimal 类、日期类)
一、Math 类(P481) Math 类包含,用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。 (1)abs:绝对值 (2)pow:求幂 (3)c…...

2023年12月24日学习总结
今日to do list: 做kaggle上面的流量预测项目☠️ 学习时不刷手机🤡 okkkkkkkkkkkkkk 开始👍🍎 0、我在干什么? 我在预测一个名字叫做elborn基站的下行链路流量,用过去29天的数据预测未来10天的数据 1、…...

第26关 K8s日志收集揭秘:利用Log-pilot收集POD内业务日志文件
------> 课程视频同步分享在今日头条和B站 大家好,我是博哥爱运维。 OK,到目前为止,我们的服务顺利容器化并上了K8s,同时也能通过外部网络进行请求访问,相关的服务数据也能进行持久化存储了,那么接下来…...

芯科科技以卓越的企业发展和杰出的产品创新获得多项殊荣
2023年共获颁全球及囯內近20个行业奖项 Silicon Labs(亦称“芯科科技”)日前在全球半导体联盟(Global Semiconductor Alliance,GSA)举行的颁奖典礼上,再次荣获最受尊敬上市半导体企业奖,这是公…...

计算机视觉基础(11)——语义分割和实例分割
前言 在这节课,我们将学习语义分割和实例分割。在语义分割中,我们需要重点掌握语义分割的概念、常用数据集、评价指标(IoU)以及经典的语义分割方法(Deeplab系列);在实例分割中,需要知…...

CNAS中兴新支点——什么是软件压力测试?软件压力测试工具和流程
一、含义:软件压力测试是一种测试应用程序性能的方法,通过模拟大量用户并发访问,测试应用程序在压力情况下的表现和响应能力。软件压力测试的目的是发现系统潜在的问题,如内存泄漏、线程锁、资源泄漏等,以及在高峰期或…...

jQuery: 整理3---操作元素的内容
1.html("内容") ->设置元素的内容,包含html标签(非表单元素) <div id"html1"></div><div id"html2"></div>$("#html1").html("<h2>上海</h2>") …...

22、商城系统(四):项目jar包配置(重要),网关配置,商品服务基础数据设置
目录 0.重要:整个项目的配置 最外层的pom.xml renren-fast renren-generator xpmall-common xpmall-coupon...

循环链表的学习以及问题汇总
[TOC](循环链表常见的问题) # 问题一: **报错**  **报错原因:**因为没有提前对_tag_CircleListNode重命名为CircleListNode,所以,在定义…...

C++期末复习总结继承
继承是软件复用的一种形式,他是在现有类的基础上建立新类,新类继承了现有类的属性和方法,并且还拥有了其特有的属性和方法,继承的过程称为派生,新建的类称为派生类(子类),原有的成为…...

CloudCanal x Debezium 打造实时数据流动新范式
简述 Debezium 是一个开源的数据订阅工具,主要功能为捕获数据库变更事件发送到 Kafka。 CloudCanal 近期实现了从 Kafka 消费 Debezium 格式数据,将其 同步到 StarRocks、Doris、Elasticsearch、MongoDB、ClickHouse 等 12 种数据库和数仓,…...

Nodejs+Express搭建HTTPS服务
最近开发需要搭建一个https的服务,正好最近在用nodejs和express,于是乎想到就近就使用这两东西来搭建一个https的服务吧。这里搭建过程总共需要两步,第一步生成证书,第二步使用https模块启动服务。 生成自签名证书 这里因为是自…...

设计模式之-策略模式,快速掌握策略模式,通俗易懂的讲解策略模式以及它的使用场景
系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用…...

【leetcode100-019】【矩阵】螺旋矩阵
【题干】 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 【思路】 不难注意到,每进行一次转向,都有一行/列被输出(并失效);既然已经失效,那我…...

【计算机视觉中的多视图几何系列】深入浅出理解针孔相机模型
温故而知新,可以为师矣! 一、参考资料 《计算机视觉中的多视图几何-第五章》-Richard Hartley, Andrew Zisserman. 二、针孔模型相关介绍 1. 重要概念 1.1 投影中心/摄像机中心/光心 投影中心称为摄像机中心,也称为光心。投影中心位于一…...

轻量级Python IDE使用(三)——函数
1、函数 1.1、函数的概述 在程序设计中,函数的使用可以提升代码的复用率和可维护性。 系统内建函数pow()进行幂运算: a pow(2,4)自定义函数func() def func(a,b):return a ** b afunc(2,4) print(a)自定义函数func(),功能是输出a的b次幂 1.2、函数的定义 py…...

计算机图形学理论(3):着色器编程
本系列根据国外一个图形小哥的讲解为本,整合互联网的一些资料,结合自己的一些理解。 CPU vs GPU CPU支持: 快速缓存分支适应性高性能 GPU支持: 多个 ALU快速板载内存并行任务的高吞吐量(在每个片段、顶点上执行着色…...

ubuntu20.04安装timeshift最新方法
总结: 现在可以使用如下代码安装 sudo apt-get update sudo apt-get install timeshift原因: 在尝试Timeshift系统备份与还原中的方法时, sudo apt-add-repository -y ppa:teejee2008/ppa运行失败。 更改为以下代码: sudo a…...

小狐狸ChatGPT付费创作系统小程序端开发工具提示打开显示无法打开页面解决办法
最新版2.6.7版下载:https://download.csdn.net/download/mo3408/88656497 很多会员在上传小程序前端时经常出现首页无法打开的情况,错误提示无法打开该页面,不支持打开,这种问题其实就是权限问题,页面是通过调用web-v…...

DQL-基本查询
概念: 1,数据库管理系统一个重要功能就是数据查询,数据查询不应只是简单返回数据库中存储的数据,还应该根据需要对数据进行筛选以及确定数据以什么样的格式显示 2,MySQL提供了功能强大、灵活的语句来实现这些操作 3…...