JavaScript面试题整理(一)
数据类型篇
1、JavaScript有哪些数据类型,它们的区别是什么?
基本数据类型:number、string、boolean、undefined、NaN、BigInt、Symbol
引入数据类型:Object
NaN是JS中的特殊值,表示非数字,NaN不是数字,但是它的数据类型是数字,它不等于任何值,包括自身,在布尔运算时被当做false,NaN与任何数运算得到的结果都是NaN,计算失败或者运算无法返回正确的数值的情况下就会返回NaN。一些数学函数的运算结果也会出现NaN。
其中Sysmbol和BigInt是ES6中新增的数据类型:
(1)Symbol代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题。
(2)BigInt是一种数字类型的数据,它可以表示任意精度格式的整数,使用BigInt可以安全地存储和操作大整数,即使这个数已经超出了Number能够表示的安全整数范围。
以上这些数据类型可以分为原始数据类型和引用数据类型
- 栈:原始数据类型(Undefined、Null、Boolean、Number、String)
- 堆:引用数据类型(对象、数组和函数)
2、基本数据类型和引用数据类型的区别
1、基本数据类型是按值访问的、也就是说我们可以操作保存在变量中的实际的值。
2、基本数据类型的值是不可变的,任何方法都无法改变一个基本类型的值,当这个变量重新赋值后看起来变量的值是改变了,但是这里的变量名只是指向变量的一个指针,所以改变的是指针的指向改变,该变量是不变的,但是引用类型可以改变。
3、基本数据类型不可以添加属性和方法,但是引用类型可以。
4、基本数据类型的赋值是简单赋值,如果从一个变量向另一个变量赋值基本类型的值,会在变量对象上创建一个新值,然后把该值复制搭配为新变量分配的位置上,引用数据类型的赋值是对象引用。
5、基本数据类型的比较是值的比较,引用类型的比较是引用的比较,比较对象的内存地址是否相同。
6、基本数据类型是存放在栈区的,引用数据类型同时保存在栈区和堆区。
3、数据类型检测的方法有哪些?
(1)typeof
console.log(typeof 2); //numberconsole.log(typeof true); //booleanconsole.log(typeof 'str'); //stringconsole.log(typeof []); //objectconsole.log(typeof function(){}); //functionconsole.log(typeof {}); //objectconsole.log(typeof undefined); //undefinedconsole.log(typeof null); //object
其中数组、对象、null都会被判断为object,其他判断都正确。
(2)instanceof
instanceof可以正确判断对象的类型,其内部运行机制是判断再起原型链中能否找到该类型的原型
console.log(2 instanceof Number); //falseconsole.log(true instanceof Boolean); //falseconsole.log('str' instanceof String); //falseconsole.log([] instanceof Array); //trueconsole.log(function(){} instanceof Function); //trueconsole.log({} instanceof Object); //true
由以上代码可以看出,instanceof只能正确判断引用数据类型,而不能判断基本数据类型。instanceof运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性。
(3)constructor
console.log((2).constructor === Number); //trueconsole.log((true).constructor === Boolean); //trueconsole.log(('str').constructor === String); //trueconsole.log(([]).constructor === Array); //trueconsole.log((function(){}).constructor === Function); //trueconsole.log(({}).constructor === Object); //true
constructor有两个作用,一是判断数据的类型,二是对象实例通过constructor对象访问它的构造函数。需要注意的是:如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了。
function Fn(){}Fn.prototype = new Array();let f = new Fn();console.log(f.constructor === Fn); //falseconsole.log(f.constructor === Array); //true
(4)Object.prototype.toString.call()
Object.prototype.toString.call()使用Object对象的原型方法toString来判断数据类型。
let a = Object.prototype.toString;console.log(a.call(2)); //[object Number]console.log(a.call(true)); //[object Boolean]console.log(a.call('str')); //[object String]console.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]
同样是检测对象obj调用toString方法,obj.String()的结果和Object.prototype.toString.call(obj)的结果却不一样,这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串...),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。
4、null和undefined的区别
undefined:未定义的值
得到undefined的方式:
1、声明一个变量,但没有赋值
2、访问对象上不存在的属性
3、函数定义了形参,但没有传递实参
4、使用函数的返回值,当没有return操作时,就默认返回一个原始的状态值,这个值就是undefined,表名函数的单回执未被定义。
5、使用void对表达式求值 ECMAScript明确规定void操作符,对任何表达式求值都返回
null:代表空值
区别:undefined表示一个变量自然的、最原始的状态值,而null则表示一个变量被人为的设置为空对象,而不是原始状态。所以,在实际使用过程中,为了保证变量所代表的的语义,不要对一个变量显式的赋值undefined,当需要释放一个对象时,直接赋值为null即可。
当对这两种类型使用typeof进行判断时,Null类型化会返回‘object’,这是一个历史遗留问题,当使用‘==’对这两种类型的值进行比较时会返回true,使用‘===’时会返回false。
5、为什么typeof null得到object而不是null?
typeof null的结果是Object。因为JavaScript中不同对象在底层都表示为二进制,二JavaScript中会把二进制前三位都为0的判断为object类型,而null的二进制表示全都是0,自然前三位也是0,所以执行typeof时会返回‘object’。
在JavaScript第一个版本中,所有值都存储在32位的单元中,每个单元包含一个小的类型标签(1-3 bits)以及当前要存储值的真实数据。类型标签存储在每个单元的低位中,共有5种数据类型:
000:object -当前存储的数据指向一个对象
1:int -当前存储的数据是一个31位的有符号整数
010:double -当前存储的数据指向一个双精度的浮点数
100:string -当前存储的数据指向一个字符串
110:boolean -当前存储的数据是布尔值
如果最低位是1,则类型标签标志位的长度只有一位;如果最低位是0,则类型标签标志位的长度占3位,为存储其他四种数据类型提供了额外两个bit的长度。
但是有两个特殊的数据类型:
undefined的值是(-2)30(一个超出整数范围的数字)
null的值是机器码NULL指针(null的指针的值全是0)
也就是说null的类型标签也是000,和object的类型标签一样,所以会被判定为Object。
6、为什么null==undefined 得到true 但是null===undefined得到 false ?
要比较相等性之前,不能将null和undefined转换成其他任何值,但null == undefined会返回true。ECMAScript规范中是这样定义的。
原因:null:Null类型,代表‘空值’,代表一个空对象指针,使用typeof运算得到‘object’,所以你可以认为它是一个特殊的对象值。
undefined:Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。
实际上,undefined值是派生自null值的,ECMAScript标准规定对二者进行相等性测试要返回true。
7、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);}
}
8、为什么0.1+0.2 !== 0.3,如果让其相等?
在开发过程中遇到类似这样的问题:
let n1 = 0.1,n2=0.2
console.log(n1+n2) //0.30000000000000004
这里得到的不是想要的结果,如果要想等于0.3,就要进行转换:(n1+n2).toFixed(2)
toFixed(num)方法可以把Number四舍五入为指定小数位的数字。但是出现这样的结果其实是因为计算机是通过二进制的方式存储数据的,所以计算机计算0.1+0.2的时候,实际上是计算的两个数的二进制的和。0.1的二进制是0.00010011001100...(1100循环),0.2的二进制是0.00110011001100...(1100循环),这两个数的二进制都是无限循环的数。而JavaScript处理无限循环的二进制小数时,一般我们认为数字包括小数和整数,但是在JavaScript中只有一种数字类型Number,它的实现遵循IEEE 754标砖,使用64位固定长度来表示,也就是标准的double双精度浮点数。在二进制科学表示法中,双精度浮点数的小数部分最多只能保留52位,再加上前面的1,其实就是保留53位有效数字,剩余的需要舍去,遵从‘0舍1入’的原则。
根据这个原则,0.1和0.2的二进制数相加,再转换为十进制数就是0.30000000000000004
而对于这种情况,最直接的解决方法就是设置一个误差范围,通常称为‘机器精度’。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 === 0.3
function NumberEpsilon(arg1,arg2) { return Math.abs(arg1-arg2) < Number.EPSILON;
}
console.log(NumberEpsilon(0.1+0.2,0.3)); //true
9、如何获取安全的undefined值?
因为undefined是一个标识符,所以可以被当作变量来使用和赋值,但是这样会影响undefined的正常判断。表达式void___没有返回值,因此返回结果是undefined。void并不改变表达式的结果,只是让表达式不返回值。因此可以用void()来获得undefined。
10、typeof NaN的结果是什么
NaN的意思是不是一个数字(Not a number),NaN是一个警戒值,用于指出数字类型中的错误情况,即执行数学运算但是没有成功,这是失败后返回的结果。
console.log(typeof NaN); //number
NaN是一个特殊值,它和自身不相等,是唯一一个非自反(自反,reflexive,即x===x不成立)的值。而NaN !== NaN为true
11、isNaN和Number.isNaN函数的区别
- 函数isNaN接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的值都会返回true,因此非数字的值传入也会返回true,会影响NaN的判断
- 函数Number.isNaN会首先判断传入的参数是否为数字,如果是数字再继续判断是否为NaN,不会进行数据类型的转换,这种方法对于NaN的判断更为准确。
12、==操作符的强制类型转换规则
对于 == 来说,如果对比双方的类型不一样,就会进行类型转换。假如对比x和y是否相同,就会进行如下判断流程:
1、首先会判断两者类型是否相同,相同的话就比较两者的大小
2、类型不相同的话,就会进行类型转换
3、会先判断是否在对比null和undefined,是的话就返回true
4、判断两者类型是否为string和number,是的话就会将字符串转换为number
1 == ‘1’
1 == 1
5、判断其中一方是否为boolean,是的话就会把boolean转为number再进行判断
‘1’ == true
‘1’ == 1
1 == 1
6、判断其中一方是都为object且另一方为string、number或者symbol,是的话就会把object转为原始类型再进行判断
‘1’ == {name:'js'}
'1' == '[object.Object]'
相关文章:
JavaScript面试题整理(一)
数据类型篇 1、JavaScript有哪些数据类型,它们的区别是什么? 基本数据类型:number、string、boolean、undefined、NaN、BigInt、Symbol 引入数据类型:Object NaN是JS中的特殊值,表示非数字,NaN不是数字…...
数据结构:树和二叉树之-堆排列 (万字详解)
目录 树概念及结构 1.1树的概念 1.2树的表示 编辑2.二叉树概念及结构 2.1概念 2.2数据结构中的二叉树:编辑 2.3特殊的二叉树: 编辑 2.4 二叉树的存储结构 2.4.1 顺序存储: 2.4.2 链式存储: 二叉树的实现及大小堆…...
爬虫入门基础:深入解析HTTP协议的工作过程
目录 一、HTTP协议简介 二、HTTP协议的工作过程 三、请求方法与常见用途 四、请求头与常见字段 五、状态码与常见含义 六、进阶话题和注意事项 总结 在如今这个数字化时代,互联网已经成为我们获取信息、交流和娱乐的主要渠道。而在互联网中,HTTP协…...
k8备份与恢复-Velero
简介 Velero 是一款可以安全的备份、恢复和迁移 Kubernetes 集群资源和持久卷等资源的备份恢复软件。 Velero 实现的 kubernetes 资源备份能力,可以轻松实现 Kubernetes 集群的数据备份和恢复、复制 kubernetes 集群资源到其他kubernetes 集群或者快速复制生产环境…...
基于Python开发的火车票分析助手(源码+可执行程序+程序配置说明书+程序使用说明书)
一、项目简介 本项目是一套基于Python开发的火车票分析助手,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含:项目源码、项目文档等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,…...
旺店通·企业奇门与金蝶云星空对接集成订单查询连通销售订单新增(旺店通销售-金蝶销售订单-小红书)
旺店通企业奇门与金蝶云星空对接集成订单查询连通销售订单新增(旺店通销售-金蝶销售订单-小红书) 接通系统:旺店通企业奇门 慧策最先以旺店通ERP切入商家核心管理痛点——订单管理,之后围绕电商经营管理中的核心管理诉求,先后布局流量获取、会…...
卡尔曼滤波应用在数据处理方面的应用
卡尔曼滤波应用到交通领域 滤波器介绍核心思想核心公式一维卡尔曼滤波器示例导入所需的库 滤波器介绍 卡尔曼滤波器是一种用于估计系统状态的数学方法,它以卡尔曼核心思想为基础,广泛应用于估计动态系统的状态和滤除测量中的噪声。以下是卡尔曼滤波器的核…...
PROFIBUS主站转ETHERCAT协议网关
产品介绍 JM-DPM-ECT是自主研发的一款PROFIBUS-DP主站功能的通讯网关。该产品主要功能是将各种PROFIBUS-DP从站接入到ETHERCAT网络中。 本网关连接到PROFIBUS总线中作为主站使用,连接到ETHERCAT总线中作为从站使用。 产品参数 技术参数 ◆ PROFIBUS-DP/V0 协议符…...
Vue路由的使用及node.js下载安装和环境搭建
目录 一、Vue路由 1.1 简介 ( 1 ) 特点 ( 2 ) 作用 1.2 实例 ( 1 ) 引入 ( 2 ) 组件 ( 3 ) 关系 ( 4 ) 路由 ( 5 ) 事件 ( 6 ) 锚点 二、nodeJS 2.1 下载 2.2 安装 2.3 环境搭建 新增 添加 测试 配置 运行 一、Vue路由 1.1 简介 Vue路由是Vue.…...
【算法训练-二叉树 三】【最大深度与直径】求二叉树的最大深度、求二叉树的直径
废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【求二叉树的直径】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件…...
查看linux是centos还是Ubuntu
查看linux是centos还是Ubuntu 命令:cat /etc/os-release...
win10怎么关闭自动更新,这个方法你知道吗?
Windows 10 操作系统自动更新是确保系统安全性和性能的关键功能。然而,有时用户可能希望手动控制更新,因此关闭自动更新可能是一个有用的选项。在本文中,我们将介绍win10怎么关闭自动更新的两种方法,以满足用户不同的需求。 方法1…...
「语音芯片」常见的OTP芯片故障分析
OTP语音芯片是指一次性可编程语音芯片,语音只能烧写一次,适合应用在不需要修改语音、语音长度短的场合,从放音的长度上可以分为20秒、40秒、80秒、170秒、340秒。语音芯片的特点是单芯片方案、价格便宜,适合批量生产,即便是小数量…...
孩子写作业买什么样台灯合适?适合孩子读写台灯推荐
现在孩子的普遍都存在视力问题,而导致孩子近视的原因可能跟光线太强或太弱、不用的用眼习惯、长时间的过度用眼等因素有关,根据数据表明目前中国近视患者人数达到6亿多,其中儿童青少年的视力不良率甚至高达八成,所以在孩子的学习道…...
DBAPI插件开发指南
DBAPI插件开发指南 插件市场 您可以去插件市场下载插件 插件的作用 DBAPI的插件分4类,分别是数据转换插件、缓存插件、告警插件、全局数据转化插件 缓存插件 对执行器结果进行缓存,比如SQL执行器,对查询类SQL,sql查询结果进…...
线程池使用之自定义线程池
目录 一:Java内置线程池原理剖析 二:ThreadPoolExecutor参数详解 三:线程池工作流程总结示意图 四:自定义线程池-参数设计分析 1:核心线程数(corePoolSize) 2:任务队列长度(workQueue) 3:最大线程数(maximumPoolSize) 4:最…...
Puppeteer无头浏览器:开启自动化之门,掌握浏览器世界的无限可能
大概还是入门期,我曾用Puppeteer做爬虫工具以此来绕过某网站的防爬机制。近期有需求要做任意链接网页截图,像这种场景非常适合用Puppeteer完成。无头浏览器我已知的还有Selenium。 完成截图需求踩的最大的坑不是具体的逻辑代码,而是Docker部…...
Ubuntu 23.10/24.04 LTS 放弃默认使用 snap 版 CUPS 打印堆栈
导读Canonical 的开发者、OpenPrinting 的项目负责人 Till Kamppeter 今年 5 月表示,计划在 Ubuntu 23.10(Mantic Minotaur)上默认使用 Snap 版本的 CUPS 打印堆栈。 不过经过数月的测试,官方放弃了这项决定。Ubuntu 23.10&#x…...
Linux CentOS7 history命令
linux查看历史命令可以使用history命令,该命令可以列出所有已键入的命令。 这个命令的作用可以让用户或其他有权限人员,进行审计,查看已录入的命令。 用户所键入的命令作为应保存的信息将记录在文件中,这个文件就是家目录中的一…...
XC5350A 单节锂电池保护芯片 过放2.9V/2.8V/2.4V保护IC
XC5350A产品是一个高集成度的鲤离子/聚合物电池保护解决方案。XC5350A包含先进的功率MOSFET,高精度电压检测电路和延迟电路XC5350A放入一个超小型SOT23-5封装,只有一个外部元件使其成为在电池组有限的空间的理想解决方案。 XC5350A具有包括过充ÿ…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
