JS面试常见问题——数据类型篇

news2025/6/10 4:48:31

这几周在进行系统的复习,这一篇来说一下自己复习的JS数据结构的常见面试题中比较重要的一部分

文章目录

    • 一、JavaScript有哪些数据类型
    • 二、数据类型检测的方法
      • 1. typeof
      • 2. instanceof
      • 3. constructor
      • 4. Object.prototype.toString.call()
      • 5. type null会被判断为Object,为什么
      • 6. typeof NaN的结果是什么
    • 三、判断数组的方式有哪些
      • 1. Object.prototype.toString.call()
      • 2. 通过原型链判断
      • 3. 通过ES6的Array.isArray()做判断
      • 4. 通过instanceof判断
      • 5. 通过Array.prototype.isPrototypeOf()
    • 四、null和undefined的区别
    • 五、instanceof操作符的实现原理及实现
    • 六、为什么0.1+0.2 !== 0.3,如何让其相等
      • 1. 原因
      • 2. 如何解决
    • 七、==操作符的强制类型转换规则
    • 八、Object.is()与比较操作符“=== ”、“ ==”的区别
    • 九、其他值到字符串的转换规则
    • 十、其他值到数字值的转换规则
    • 十一、其他值到布尔类型的值的转换规则
    • 十二、isNaN和Number.isNaN函数的区别
    • 十三、JavaScript中如何进行隐式类型转换
      • 1. ToPrimitive
      • 2. 隐式转换规则
      • 3. +操作符什么时候用于字符串拼接

一、JavaScript有哪些数据类型

八种:Number String Boolean Null undefined Object Symbol BigInt
Symbol & BigInt 是ES6新增的数据类型

  • Symbol 代表创建后独一无二且不可变的数据类型;主要是为了解决可能出现全局变量冲突的问题
  • BigInt是一种数字类型,可以表示任意精度格式的整数,使用BigInt可以安全地存储和操作大整数,即使这个数超出Number能够表示的安全整数范围

分类:原始数据类型 & 引用数据类型
栈:Number String Boolean Null Undefined(原始数据类型)
堆:Object(引用数据类型)(对象、数组、函数)
两种类型的区别在于存储位置的不同:

  • 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
  • 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

数据结构和操作系统中
堆和栈的概念存在于数据结构和操作系统内存中,在数据结构中:
● 在数据结构中,栈中数据的存取方式为先进后出。
● 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。
在操作系统中,内存被分为栈区和堆区:
● 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
● 堆区内存一般由开发着分配释放,若开发者不释放,程序结束时可能由垃圾回收机制回收。

二、数据类型检测的方法

1. typeof

注:数组、对象、null都会被判断为Object

2. instanceof

可以正确判断对象的类型,不能判断基本数据类型;可以用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性
内部运行机制是判断在其原型链中能否找到该类型的原型

3. constructor

判断数据的类型;对象实例通过constructor对象访问它的构造函数;如果创建一个对象来改变他的原型,constructor就不能用来判断数据类型了

4. Object.prototype.toString.call()

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

同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?
这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。

5. type null会被判断为Object,为什么

在 JavaScript 第一个版本中,所有值都存储在 32 位的单元中,每个单元包含一个小的 类型标签(1-3 bits) 以及当前要存储值的真实数据。类型标签存储在每个单元的低位中,共有五种数据类型:

000: object - 当前存储的数据指向一个对象。
1: int - 当前存储的数据是一个 31 位的有符号整数。
010: double - 当前存储的数据指向一个双精度的浮点数。
100: string - 当前存储的数据指向一个字符串。
110: boolean - 当前存储的数据是布尔值。
有两种特殊数据类型:
● undefined的值是 (-2)30(一个超出整数范围的数字);
● null 的值是机器码 NULL 指针(null 指针的值全是 0)
在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回 object。

6. typeof NaN的结果是什么

返回的结果:number
NaN 指“不是一个数字”(not a number),NaN 是一个“警戒值”(sentinel value,有特殊用途的常规值),用于指出数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。
NaN 是一个特殊值,它和自身不相等,是唯一一个非自反(自反,reflexive,即 x === x 不成立)的值。而 NaN !== NaN 为 true。

三、判断数组的方式有哪些

1. Object.prototype.toString.call()

Object.prototype.toString.call(obj).slice(8,-1) === 'Array';

2. 通过原型链判断

obj.__proto__ === Array.prototype;

3. 通过ES6的Array.isArray()做判断

4. 通过instanceof判断

5. 通过Array.prototype.isPrototypeOf()

四、null和undefined的区别

undefined代表的含义是未定义,当一个变量没有任何数据时也是undefined,undefined是原始数据类型之一,可以直接把undefined赋值给变量或函数返回;被迫的替代方案
null是空对象,需要主动使用,没有声明不会出现;空
判断null和undefined时需要使用严格判断(===)

五、instanceof操作符的实现原理及实现

instanceof 运算符用于判断构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。

function myInstanceof(left, right) {
  // 获取对象的原型
  let proto = Object.getPrototypeOf(left)
  // 获取构造函数的 prototype 对象
  let prototype = right.prototype; 

  // 判断构造函数的 prototype 对象是否在对象的原型链上
  while (true) {
    if (!proto) return false;
    if (proto === prototype) return true;
    // 如果没有找到,就继续从其原型上找,Object.getPrototypeOf方法用来获取指定对象的原型
    proto = Object.getPrototypeOf(proto);
  }
}

六、为什么0.1+0.2 !== 0.3,如何让其相等

1. 原因

计算机是通过二进制的方式存储数据的,所以计算机计算0.1+0.2的时候,实际上是计算的两个数的二进制的和。0.1的二进制是0.0001100110011001100…(1100循环),0.2的二进制是:0.00110011001100…(1100循环),这两个数的二进制都是无限循环的数。
但是在 JavaScript 中只有一种数字类型:Number,它的实现遵循IEEE 754标准,使用64位固定长度来表示,也就是标准的double双精度浮点数。在二进制科学表示法中,双精度浮点数的小数部分最多只能保留52位,再加上前面的1,其实就是保留53位有效数字,剩余的需要舍去,遵从“0舍1入”的原则。
根据这个原则,0.1和0.2的二进制数相加,再转化为十进制数就是:0.30000000000000004。
在这里插入图片描述

  • 第一部分(蓝色):用来存储符号位(sign),用来区分正负数,0表示正数,占用1位
  • 第二部分(绿色):用来存储指数(exponent),占用11位
  • 第三部分(红色):用来存储小数(fraction),占用52位

2. 如何解决

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3

七、==操作符的强制类型转换规则

  1. 一个布尔值,将其转换为数字比较
  2. 一个字符串,一个数字、布尔值或null,将字符串转换为数字比较。
  3. 一个对象,一个字符串、数字或符号,将对象转换为原始值比较。
    对象转换为原始值的规则如下:
  1. 如果对象有valueOf方法并返回基本类型的值,则使用该值进行比较。
  2. 如果valueOf方法返回的仍然是对象,则调用对象的toString方法,并使用返回的字符串进行比较。
  3. 如果对象没有valueOf和toString方法,或者返回的不是基本类型的值,则抛出TypeError异常。
  1. 一个null,一个undefined,则相等。
  2. 一个NaN,一个不是NaN,则相等
  3. 一个数字0,一个字符串且内容为非空,则将数字0转换为字符串再进行比较。
  4. 其他情况下,将操作数都转换为数字再进行比较。
    需要注意的是,如果两个都是对象,则比较的是它们的引用是否相等,不会进行强制类型转换。

八、Object.is()与比较操作符“=== ”、“ ==”的区别

  1. 使用双等号(==)进行相等判断时,如果两边的类型不一致,则会进行强制类型转化后再进行比较。
  2. 使用三等号(===)进行相等判断时,如果两边的类型不一致时,不会做强制类型准换,直接返回 false。
  3. 使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 是相等的。

九、其他值到字符串的转换规则

  1. Null 和 Undefined 类型 ,null 转换为 “null”,undefined 转换为 “undefined”,
  2. Boolean 类型,true 转换为 “true”,false 转换为 “false”。
  3. Number 类型的值直接转换,不过那些极小和极大的数字会使用指数形式。
  4. Symbol 类型的值直接转换,但是只允许显式强制类型转换,使用隐式强制类型转换会产生错误。
  5. 对普通对象来说,除非自行定义 toString() 方法,否则会调用 toString()(Object.prototype.toString())来返回内部属性 [[Class]] 的值,如"[object Object]"。如果对象有自己的 toString() 方法,字符串化时就会调用该方法并使用其返回值。

十、其他值到数字值的转换规则

  1. Undefined 类型的值转换为 NaN。
  2. Null 类型的值转换为 0。
  3. Boolean 类型的值,true 转换为 1,false 转换为 0。
  4. String 类型的值转换如同使用 Number() 函数进行转换,如果包含非数字值则转换为 NaN,空字符串为 0。
  5. Symbol 类型的值不能转换为数字,会报错。
  6. 对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。

为了将值转换为相应的基本类型值,抽象操作 ToPrimitive 会首先(通过内部操作 DefaultValue)检查该值是否有valueOf()吗方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用 toString() 的返回值(如果存在)来进行强制类型转换。
如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。

十一、其他值到布尔类型的值的转换规则

假值: undefined null false +0、-0 和 NaN “”
假值的布尔强制类型转换结果为false;从逻辑上说,假值表以外的应该都是真值

十二、isNaN和Number.isNaN函数的区别

  • 函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true,会影响 NaN 的判断。
  • 函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

十三、JavaScript中如何进行隐式类型转换

1. ToPrimitive

JavaScript 中每个值隐含的自带的方法,用来将值 (无论是基本类型值还是对象)转换为基本类型值。如果值为基本类型,则直接返回值本身;如果值为对象,

// @obj 需要转换的对象 
// @type 期望的结果类型
ToPrimitive(obj,type)

type的值为number或者string。
(1)当type为number时规则如下:
● 调用obj的valueOf方法,如果为原始值,则返回,否则下一步;
● 调用obj的toString方法,后续同上;
● 抛出TypeError 异常。
(2)当type为string时规则如下:

  • 调用obj的toString方法,如果为原始值,则返回,否则下一步;
  • 调用obj的valueOf方法,后续同上;
  • 抛出TypeError异常。

默认情况下:

  • 如果对象为 Date 对象,则type默认为string;
  • 其他情况下,type默认为number。

Date 以外的对象,转换为基本类型的大概规则可以概括为一个函数:

var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN

2. 隐式转换规则

隐式类型转换主要发生在+、-、*、/以及==、>、<这些运算符之间

  1. +操作符的两边有至少一个string类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。
  2. -、*、\操作符NaN也是一个数字
  3. ==操作符两边的值都尽量转成number
  4. <>如果两边都是字符串,则比较字母表顺序;其他情况下,转为数字再比较;对象会被ToPrimitive转换为基本类型再进行转换

3. +操作符什么时候用于字符串拼接

如果 + 的其中一个操作数是字符串(或者通过以上步骤最终得到字符串),则执行字符串拼接,否则执行数字加法
除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字。
|| 和 && 操作符的返回值

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

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

相关文章

【靶场】XXE-Lab xxe漏洞

前言 学习xxe漏洞,搭了个XXE-Lab的靶场 一、搭建靶场 现在需要登录,不知道用户名密码,先随便试试抓包 二、判断是否存在xxe漏洞 1.首先登录抓包 看到xml数据解析,由此判断和xxe漏洞有关,但还不确定xxe漏洞是否存在。 2.尝试xxe 漏洞 判断是否存在xxe漏洞 A.send to …

开源项目实战学习之YOLO11:12.6 ultralytics-models-tiny_encoder.py

👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 ultralytics-models-sam 1.sam-modules-tiny_encoder.py2.数据处理流程3.代码架构图(类层次与依赖)blocks.py: 定义模型中的各种模块结构 ,如卷积块、残差块等基础构建…

Python[数据结构及算法 --- 栈]

一.栈的概念 在 Python 中&#xff0c;栈&#xff08;Stack&#xff09;是一种 “ 后进先出&#xff08;LIFO&#xff09;”的数据结构&#xff0c;仅允许在栈顶进行插入&#xff08;push&#xff09;和删除&#xff08;pop&#xff09;操作。 二.栈的抽象数据类型 1.抽象数…

Unity VR/MR开发-开发环境准备

视频讲解链接&#xff1a; 【XR马斯维】UnityVR/MR开发环境准备【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili

2025-06-08-深度学习网络介绍(语义分割,实例分割,目标检测)

深度学习网络介绍(语义分割,实例分割,目标检测) 前言 在开始这篇文章之前&#xff0c;我们得首先弄明白&#xff0c;什么是图像分割&#xff1f; 我们知道一个图像只不过是许多像素的集合。图像分割分类是对图像中属于特定类别的像素进行分类的过程&#xff0c;即像素级别的…

【Ragflow】26.RagflowPlus(v0.4.0):完善解析逻辑/文档撰写模式全新升级

概述 在历经半个月的间歇性开发后&#xff0c;RagflowPlus再次迎来一轮升级&#xff0c;正式发布v0.4.0。 开源地址&#xff1a;https://github.com/zstar1003/ragflow-plus 更新方法 下载仓库最新代码&#xff1a; git clone https://github.com/zstar1003/ragflow-plus.…

智能照明系统:具备认知能力的“光神经网络”

智能照明系统是物联网技术与传统照明深度融合的产物&#xff0c;其本质是通过感知环境、解析需求、自主决策的闭环控制&#xff0c;重构光与人、空间、环境的关系。这一系统由智能光源、多维传感器、边缘计算单元及云端管理平台构成&#xff0c;形成具备认知能力的“光神经网络…

SpringSecurity+vue通用权限系统

SpringSecurityvue通用权限系统 采用主流的技术栈实现&#xff0c;Mysql数据库&#xff0c;SpringBoot2Mybatis Plus后端&#xff0c;redis缓存&#xff0c;安全框架 SpringSecurity &#xff0c;Vue3.2Element Plus实现后台管理。基于JWT技术实现前后端分离。项目开发同时采 …

短视频时长预估算法调研

weighted LR o d d s T p 1 − p ( 1 − p ) o d d s T p ( T p o d d s ∗ p ) o d d s p o d d s T o d d s odds \frac{Tp}{1-p} \newline (1-p)odds Tp \newline (Tp odds * p) odds \newline p \frac{odds}{T odds} \newline odds1−pTp​(1−p)oddsTp(Tpodds…

设计模式域——软件设计模式全集

摘要 软件设计模式是软件工程领域中经过验证的、可复用的解决方案&#xff0c;旨在解决常见的软件设计问题。它们是软件开发经验的总结&#xff0c;能够帮助开发人员在设计阶段快速找到合适的解决方案&#xff0c;提高代码的可维护性、可扩展性和可复用性。设计模式主要分为三…

FTPS、HTTPS、SMTPS以及WebSockets over TLS的概念及其应用场景

一、什么是FTPS&#xff1f; FTPS&#xff0c;英文全称File Transfer Protocol with support for Transport Layer Security (SSL/TLS)&#xff0c;安全文件传输协议&#xff0c;是一种对常用的文件传输协议(FTP)添加传输层安全(TLS)和安全套接层(SSL)加密协议支持的扩展协议。…

Python 解释器安装全攻略(适用于 Linux / Windows / macOS)

目录 一、Windows安装Python解释器1.1 下载并安装Python解释1.2 测试安装是否成功1.3 设置pip的国内镜像------永久配置 二、macOS安装Python解释器三、Linux下安装Python解释器3.1 Rocky8.10/Rocky9.5安装Python解释器3.2 Ubuntu2204/Ubuntu2404安装Python解释器3.3 设置pip的…

Java多线程从入门到精通

一、基础概念 1.1 进程与线程 进程是指运行中的程序。 比如我们使用浏览器&#xff0c;需要启动这个程序&#xff0c;操作系统会给这个程序分配一定的资源&#xff08;占用内存资源&#xff09;。 线程是CPU调度的基本单位&#xff0c;每个线程执行的都是某一个进程的代码的某…

【芯片仿真中的X值:隐藏的陷阱与应对之道】

在芯片设计的世界里&#xff0c;X值&#xff08;不定态&#xff09;就像一个潜伏的幽灵。它可能让仿真测试顺利通过&#xff0c;却在芯片流片后引发灾难性后果。本文将揭开X值的本质&#xff0c;探讨其危害&#xff0c;并分享高效调试与预防的实战经验。    一、X值的本质与致…

python3GUI--基于PyQt5+DeepSort+YOLOv8智能人员入侵检测系统(详细图文介绍)

文章目录 一&#xff0e;前言二&#xff0e;技术介绍1.PyQt52.DeepSort3.卡尔曼滤波4.YOLOv85.SQLite36.多线程7.入侵人员检测8.ROI区域 三&#xff0e;核心功能1.登录注册1.登录2.注册 2.主界面1.主界面简介2.数据输入3.参数配置4.告警配置5.操作控制台6.核心内容显示区域7.检…

5. TypeScript 类型缩小

在 TypeScript 中&#xff0c;类型缩小&#xff08;Narrowing&#xff09;是指根据特定条件将变量的类型细化为更具体的过程。它帮助开发者编写更精确、更准确的代码&#xff0c;确保变量在运行时只以符合其类型的方式进行处理。 一、instanceof 缩小类型 TypeScript 中的 in…

【QT】qtdesigner中将控件提升为自定义控件后,css设置样式不生效(已解决,图文详情)

目录 0.背景 1.解决思路 2.详细代码 0.背景 实际项目中遇到的问题&#xff0c;描述如下&#xff1a; 我在qtdesigner用界面拖了一个QTableView控件&#xff0c;object name为【tableView_electrode】&#xff0c;然后【提升为】了自定义的类【Steer_Electrode_Table】&…

【Docker 02】Docker 安装

&#x1f308; 一、各版本的平台支持情况 ⭐ 1. Server 版本 Server 版本的 Docker 就只有个命令行&#xff0c;没有界面。 Platformx86_64 / amd64arm64 / aarch64arm(32 - bit)s390xCentOs√√Debian√√√Fedora√√Raspbian√RHEL√SLES√Ubuntu√√√√Binaries√√√ …

论文笔记:Large Language Models for Next Point-of-Interest Recommendation

SIGIR 2024 1 intro 传统的基于数值的POI推荐方法在处理上下文信息时存在两个主要限制 需要将异构的LBSN数据转换为数字&#xff0c;这可能导致上下文信息的固有含义丢失仅依赖于统计和人为设计来理解上下文信息&#xff0c;缺乏对上下文信息提供的语义概念的理解 ——>使用…

LeetCode 2894.分类求和并作差

目录 题目&#xff1a; 题目描述&#xff1a; 题目链接&#xff1a; 思路&#xff1a; 思路一详解&#xff08;遍历 判断&#xff09;&#xff1a; 思路二详解&#xff08;数学规律/公式&#xff09;&#xff1a; 代码&#xff1a; Java思路一&#xff08;遍历 判断&a…