前端知识图谱 - JavaScript基础(变量和类型)

news2024/12/21 12:02:12

变量和类型

1. JavaScript 规定了几种语言类型?

JavaScript 语言的每一个值都属于某一种数据类型,它规定了 7 种语言类型。语言类型广泛用于变量、函数参数、表达式、函数返回值等场合,根据最新的语言标准,这 7 种语言类型如下:

  • Undefined
    Undefined 类型表示未定义,任何一个变量未定义之前都是 Undefined类型,值为 undefined。但需要我们注意的是,undefined 不是一个关键字,它可以作为一个变量被定义,所以当我们为一个变量直接赋值 undefined 的时候,有可能和预期效果出现偏差。
const undefined: number = 123;
const udf: number = undefined;	// echo 123

严谨一点的话,我们可以使用 void 运算,来把任意表达式转换为 undefined。例如:

const udf: undefined = void 0; // echo undefined

但在实际编程中,我们一般不会给 Undefined 类型的值赋值,这样可以保证它是一个未赋值的自然状态,从而让它的值为 undefined。

  • Null
    Null 类型表示定义了但为空,它和 undefined 还是有一定区别的。

  • String
    String 类型用来表示文本数据,只读。

  • Boolean
    Boolean 类型有两个值,用关键字 true 和 false 来表示逻辑意义上的真和假。

  • Number
    Number 类型表示通常意义上的数字,大致对应数学中的有理数。
    JavaScript 中的 Number 类型基本符合 IEEE 754-2008 规定的双精度浮点数规则,但它为特定的几个语言场景规定了几种特殊情况:

    • Infinity:无穷大。当一个数字除以 0 时,得到的结果就是 Infinity。
    • NaN:非数字。当一个数字和一个非数字(例如字符串)作加法之外的运算时,得到的结果就是 NaN。

    根据双精度浮点数的定义,Number 类型中有效的整数范围是 -0x1fffffffffffff 至 0x1fffffffffffff,所以 Number 无法精确表示此范围外的整数。
    根据双精度浮点数的定义,非整数的 Number 无法用 == 或 === 来比较。它也造成了一个 精度丢失 的问题:

    0.1 + 0.2 == 0.3	// echo false
    

    这里我们需要换一种比较方法:使用 JS 提供的最小精度值。

    Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON	// echo true
    
    最大数字:Number.MAX_VALUE = 1.7976931348623157e+308
    最大安全数字:Number.MAX_SAFE_INTEGER = 2 ^53 - 1 = 9007199254740991
    
  • Symbol
    自ECMAScript 2015起,Symbol 成为了一种新的原生类型,就像 Number 和 String 一样,表示独一无二的值。

  • Object
    Object 类型是 JS 中最复杂的类型,也是 JS 的核心机制之一,是一种无序的键值对集合。

2. 如何避免 JavaScript 浮点数运算精度丢失?

我们先来看一个经典问题:0.1 + 0.2 != 0.3

0.1 + 0.2 == 0.3	// echo false
0.1 + 0.2			// 0.30000000000000004
(0.1 + 0.2) * 10e16	// echo 30000000000000004

可以看到,相加的结果和预期差了一个微小值,我们后期计算的话就会出现误差。
为什么会这样呢?我们先来看看运算过程:小数转换二进制用的是 乘2取整法,就是不断乘2,小数为0为止,顺序排列。
通过计算,可得:

0.1 = 0.0001100(1100) = 2^-4 * 1.1001100(1100) // 1100循环
0.2 = 0.001100(1100) = 2^-3 * 1.1001100(1100)

JS 中数字存储使用的是 ieee 754 64位双精度浮点数,64 位中第 1 位为符号位,0 正 1 负;之后 11 位为指数位,用来确定范围;其余 52 位都是尾数位,用来确定精度。
由于 0.1 和 0.2 都是无限循环的二进制,保留位数 52 位,不算最左边整数位。最终计算机中存储的数位:

0.1 = 2^-4 * 1.100 11001100 11001100 11001100 11001100 11001100 11001100 1
0.2 = 2^-3 * 1.100 11001100 11001100 11001100 11001100 11001100 11001100 1

0.00011001100110011001100110011001100110011001100110011001
+
0.0011001100110011001100110011001100110011001100110011001
=
0.01001100110011001100110011001100110011001100110011001011
// 保留 52 为,末位进位(逢1进1)
0.01 00110011 00110011 00110011 00110011 00110011 00110011 00110.30000000000000004

原生解决办法:

parseFloat((0.1 + 0.2).toFixed(10))

或者使用像 decimal.js 这样的库,它们提供了更加精确的浮点数处理能力。

3. JavaScript 对象的底层数据结构是什么?

JavaScript 对象的底层数据结构并没有在规范中明确定义,不同的 JavaScript 引擎可能会采用不同的实现方式。在当前的主流 JavaScript 引擎中,比如 V8 引擎(Chrome 和 Node.js 使用的引擎),JavaScript 对象的底层实现是基于哈希表的。

哈希表是一种能够快速查找元素的数据结构,它通过计算元素的哈希值(一个用于确定元素位置的数字)来存储元素。当你访问对象的属性时,引擎会计算属性名的哈希值,并用它来快速找到相应的属性值。

需要注意的是,虽然大多数现代 JavaScript 引擎使用哈希表作为对象的底层数据结构,但这并不是规范规定的实现方式,不同的实现可能会有所不同。

4. 理解值类型和引用类型

值类型和引用类型是编程语言数据类型的两种基本分类,它们在内存中的存储和传递方式不同。

值类型又称为原始类型或原始值(primitive value),这类值直接存储在栈(Stack)内存中,基础数据类型的值不可修改。当我们定义一个变量,为它赋值时,可以理解为,我们为这个变量绑定了一个内存空间,值就存储在这个内存空间中。
我们定义两个基本类型的变量,把一个值赋值给另一个值,会进行值的复制,这两个变量的值是相互独立的,修改一个变量的值不会影响另一个变量的值。

引用类型的变量存储在栈上,但它们指向的对象存储在堆(Heap)上。堆是内存中的动态区域,相当于自留空间,程序在运行期间会动态分配给堆栈。堆中存储的一般都是对象,然后在栈内存中存储一个变量指针,计算机通过这个变量指针,找到堆中的数据块进行操作,这种访问方式叫做按引用访问。
我们定义两个变量,其中一个为引用类型,当我们把引用类型的变量赋值给另一个变量,只是复制了对象的引用(地址),两个变量指向的是同一个值,修改一个变量会影响另一个变量的值。

5. JavaScript 中的变量在内存中的具体存储形式

同上

6. Symbol类型在实际开发中的应用,手动实现一个简单的 Symbol

了解 JavaScript Symbol 类型及其应用场景
手动实现一个 Symbol:https://segmentfault.com/a/1190000015262174

7. 至少可以说出三种判断JavaScript数据类型的方式,以及他们的优缺点,如何准确的判断数组类型

let obj = { str: "", num: 0, bool: false, nul: null, und: undefined, sym: Symbol(), arr: [] }
  1. typeof:直接返回数据的类型字段。但无法区分 NullObjectArray,它们的返回值都是 object
console.log(typeof obj.str) // 'string'
console.log(typeof obj.num) // 'number'
console.log(typeof obj.bool) // 'boolean'
console.log(typeof obj.nul) // 'object'
console.log(typeof obj.und) // 'undefined'
console.log(typeof obj.sym) // 'symbol'
console.log(typeof obj.arr) // 'object'
console.log(typeof obj) // 'object'
  1. instanceof:只能判断引用类型数据,null、understand不支持判断
obj.str instanceof String // false
obj.num instanceof Number // false
obj.bool instanceof Boolean // false
obj.nul instanceof Null // Uncaught ReferenceError: Null is not defined
obj.und instanceof Undefined // ReferenceError: Undefined is not defined
obj.sym instanceof Symbol // false
obj.arr instanceof Array // true
obj instanceof Object // true
  1. Object.prototype.toString.call():完美的判断方法。
Object.prototype.toString.call(obj.str) // '[object String]'
Object.prototype.toString.call(obj.num) // '[object Number]'
Object.prototype.toString.call(obj.bool) // '[object Boolean]'
Object.prototype.toString.call(obj.nul) // '[object Null]'
Object.prototype.toString.call(obj.und) // '[object Undefined]'
Object.prototype.toString.call(obj.sym) // '[object Symbol]'
Object.prototype.toString.call(obj.arr) // '[object Array]'
Object.prototype.toString.call(obj) // '[object Object]'
  1. Array.isArray():数组类型内置的判断方法。
Array.isArray(obj.arr) // true
Array.isArray(obj) // false

参考:
js的7中语言类型详解 - https://www.cnblogs.com/lilistyle/p/13613756.html
解析 js 中 0.1 + 0.2 != 0.3 - https://www.php.cn/faq/386908.html

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

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

相关文章

设计模式12:状态模式

系列总链接&#xff1a;《大话设计模式》学习记录_net 大话设计-CSDN博客 参考&#xff1a;设计模式之状态模式 (C 实现)_设计模式的状态模式实现-CSDN博客 1.概述 状态模式允许一个对象在其内部状态改变时改变其行为。对象看起来像是改变了其类。使用状态模式可以将状态的相…

SmartX分享:NVMe-oF 介绍、SMTX ZBS 如何选择高性能场景解决方案与如何实现

目录 背景什么是 NVMe-oFZBS AccessiSCSI 与 iSERNMVe-oF 介绍NVMeNVMe-oFNVMe-oF 承载网络&#xff08;数据平面&#xff09; ZBS NVMe-oF 实现ZBS 接入策略ZBS 接入点分配策略性能测试 为什么要支持 RoCE引用 背景 前几篇文章&#xff0c;我们认识到了 SmartX 公司产品 SMTX…

数据可视化-1. 折线图

目录 1. 折线图适用场景分析 1. 1 时间序列数据展示 1.2 趋势分析 1.3 多变量比较 1.4 数据异常检测 1.5 简洁易读的数据可视化 1.6 特定领域的应用 2. 折线图局限性 3. 折线图代码实现 3.1 Python 源代码 3.2 折线图效果&#xff08;网页显示&#xff09; 1. 折线图…

python网络框架——Django、Tornado、Flask和Twisted

Django、Tornado和flask是全栈网络框架&#xff0c;而Twisted更专注于网络底层的高性能封装&#xff0c;不提供HTML模版引擎等界面功能&#xff0c;因此不能称为全栈框架。 1、Django 发布于2003年&#xff0c;是当前python世界里最负盛名且最成熟的网络框架。相较于其他web框…

Flash语音芯片相比OTP语音芯片的优势

Flash语音芯片和OTP语音芯片是两种常见的语音解决方案&#xff0c;在各自的应用领域中发挥着重要作用。本文‌将介绍Flash语音芯片相比OTP(One-Time Programmable)语音芯片的显著优势‌。 1‌.可重复擦写‌&#xff1a;Flash语音芯片的最大特点是支持多次编程和擦除&#xff0c…

门店全域推广,线下商家营销布局的增量新高地

门店是商业中最古老的经营业态之一。很早就有行商坐贾的说法&#xff0c;坐贾指的就是门店商家&#xff0c;与经常做商品流通的「行商」相对应。 现在的门店经营&#xff0c;早已不是坐等客来&#xff0c;依靠自然流量吸引顾客上门&#xff0c;大部分的门店经营与推广都已经开…

NX系列-使用 `nmcli` 命令创建 Wi-Fi 热点并设置固定 IP 地址

使用 nmcli 命令创建 Wi-Fi 热点并设置固定 IP 地址 一、前言 在一些场景下&#xff0c;我们需要将计算机或嵌入式设备&#xff08;例如 NVIDIA Orin NX&#xff09;转换为 Wi-Fi 热点&#xff0c;以便其他设备&#xff08;如手机、笔记本等&#xff09;能够连接并使用该设备…

[react] <NavLink>自带激活属性

NavLink v6.28.0 | React Router 点谁谁就带上类名 当然类名也是可以自定义 <NavLinkto{item.link}className{({ isActive }) > (isActive ? 测试 : )}>{item.title}</NavLink> 有什么用?他会监听你的路由,刷新的话也会带上激活效果

【LC】100. 相同的树

题目描述&#xff1a; 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&…

代码随想录day24 | leetcode 93.复原IP地址 90.子集 90.子集II

93.复原IP地址 Java class Solution {List<String> result new ArrayList<String>();StringBuilder stringBuilder new StringBuilder();public List<String> restoreIpAddresses(String s) {backtracking(s, 0, 0);return result;}// number表示stringb…

Hive是什么,Hive介绍

官方网站&#xff1a;Apache Hive Hive是一个基于Hadoop的数据仓库工具&#xff0c;主要用于处理和查询存储在HDSF上的大规模数据‌。Hive通过将结构化的数据文件映射为数据库表&#xff0c;并提供类SQL的查询功能&#xff0c;使得用户可以使用SQL语句来执行复杂的​MapReduce任…

AI智能决策赋能服装零售 实现精准商品计划与供需平衡

在服装这个典型的散对散供需模型中&#xff0c;库存问题一直是零售商面临的重大挑战。如何精准预测市场需求&#xff0c;实现供需平衡&#xff0c;成为摆在零售商面前的一道难题。然而&#xff0c;随着智能决策系统的应用&#xff0c;这一切正在悄然改变。 在这个信息爆炸的时代…

RadiAnt DICOM - 基本主题 :从 PACS 服务器打开研究

正版序列号获取&#xff1a;https://r-g.io/42ZopE RadiAnt DICOM Viewer PACS 客户端功能允许您从 PACS 主机&#xff08;图片存档和通信系统&#xff09;搜索和下载研究。 在开始之前&#xff0c;您需要确保您的 PACS 服务器和 RadiAnt 已正确配置。有关配置说明&#xff0c…

VR虚拟展馆如何平衡用户隐私保护与数据收集?

在虚拟现实&#xff08;VR&#xff09;虚拟展馆的设计和运营中&#xff0c;用户隐私保护与数据收集之间的平衡是一个至关重要的议题。 接下来&#xff0c;由专业从事VR虚拟展馆制作的圆桌3D云展厅平台为大家介绍一些策略&#xff0c;可以帮助VR虚拟展馆在收集有用数据的同时&a…

46.全排列 python

全排列 题目题目描述示例 1&#xff1a;示例 2&#xff1a;示例 3&#xff1a;提示&#xff1a; 题解解决方案&#xff1a;回溯算法思路&#xff1a;Python 实现&#xff1a;复杂度分析&#xff1a; 提交结果 题目 题目描述 给定一个不含重复数字的数组 nums &#xff0c;返回…

在Win11系统上安装Android Studio

诸神缄默不语-个人CSDN博文目录 下载地址&#xff1a;https://developer.android.google.cn/studio?hlzh-cn 官方安装教程&#xff1a;https://developer.android.google.cn/studio/install?hlzh-cn 点击Next&#xff0c;默认会同时安装Android Studio和Android虚拟机&#…

基于字节大模型的论文翻译(含免费源码)

基于字节大模型的论文翻译 源代码&#xff1a; &#x1f44f; star ✨ https://github.com/boots-coder/LLM-application 展示 项目简介 本项目是一个基于大语言模型&#xff08;Large Language Model, LLM&#xff09;的论文阅读与翻译辅助工具。它通过用户界面&#xff08…

密钥.id文件连接SSH

不用设置密码&#xff0c;直接连接

run postinstall error, please remove node_modules before retry!

下载 node_modules 报错&#xff1a;run postinstall error, please remove node_modules before retry! 原因&#xff1a;node 版本出现错误&#xff0c;我的项目之前是在 12 下运行的。解决方法&#xff1a; 先卸载node_modules清除缓存将node版本切换到12重新下载即可

【ETCD】【实操篇(二)】如何从源码编译并在window上搭建etcd集群?

要在 Windows 上编译 etcd 及 etcdctl 工具&#xff0c;并使用 bat 脚本启动 etcd 集群&#xff0c;首先需要准备好开发环境并确保依赖项正确安装。下面是从 etcd 3.5 源码开始编译和启动 etcd 集群的详细步骤&#xff1a; 目录 1. 安装 Go 环境2. 获取 etcd 源码3. 编译 etcd…