JS 数据的表达

JS中数据的表达可分为数据类型、类型转换、数据声明三块。

数据类型

数据类型分成基本数据类型复杂数据类型 ,复杂数据类型都包含在全局对象 (Global)中,Global 中有全局属性全局对象 ,全局对象分为函数对象非函数对象 ,函数对象分为构造函数对象非构造函数对象

关于数据类型划分的说明:

  1. 判断是否是函数对象,就是看这个对象是否可以作为函数直接使用
  2. 判断是否是构造函数对象,就是看这个对象有没有prototype属性,即原型对象
  3. 构造函数与普通定义的函数本质上一样,只是习惯上首字母大写
  4. JS中只有 通过函数声明class声明创建的函数才是构造函数
  5. 非构造函数可以通过new关键字、函数表达式或箭头函数表达式来创建,成员函数一般都是通过这几种方式创建 的,所以一般成员函数都是非构造函数
  6. 通过函数表达式创建的函数虽然是非构造函数,但是,当使用new关键字调用时,JS会自动创建一个新的对象,并将该对象的原型设置为该函数的[[Prototype]]属性。然后,该函数内部的this关键字将指向这个新创建的对象,并在函数执行完毕后返回该对象。因此,虽然这样的函数不是构造函数,但是它们仍然可以使用new关键字来创建新的对象
  7. JS中存在一些不完整的构造函数,比如Symbol和BigInt,它们虽然是构造函数,但不能使用new关键字

基本数据类型

  • null:表示不存在,是程序级别、意料之中的没有值,如果要给某个变量或属性赋这样一个值,通常用null
  • undefined:表示未定义,是系统级别、意料之中或类似错误的没有值
  • String:表示文本值的字符序列
  • Number:表示数字
  • Boolean:表示布尔值
  • Symbol:它没有字面量语法,只能通过Symbol()获取,返回唯一值,作为对象属性标识符是它唯一的用途
  • BigInt:用于创建大于2^53-1的数字,可以用整数字面量+n的方式定义

复杂数据类型

全局属性

  • NaN:表示非数字的值
  • Infinity:表示无穷大
  • globalThis:任何上下文中引用全局对象的标准方式
  • undefined:表示未定义,是系统级别、意料之中或类似错误的没有值

全局对象

函数对象

  1. 构造函数对象
  • Function:Function是js中万物之源,所有构造函数,包括它自己都是Function的实例
  • Object:用于创建对象的构造函数。用于存储各种键值集合和更复杂的实体
  • String:表示和操作字符序列
  • Number:表示和操作数值
  • Boolean:表示和操作布尔值
  • Symbol:表示和操作Symbol类型的值
  • BigInt:表示和操作BigInt类型的值
  • Date:日期对象
  • RegExp:正则对象,用于将文本与一个模式匹配
  • Promise:用于表示一个异步操作的最终完成或失败及其结果值
  • Generator:用于生成器函数返回并且它符合可迭代协议和迭代器协议
  • AsyncFunction:为异步函数提供方法,每个异步函数都是AysncFunction对象
  • GeneratorFunction:为生成器函数提供方法,每个生成器函数都是GeneratorFunction对象
  • AsyncGeneratorFunction:为异步生成器函数提供方法,每个异步生成器函数都是AsyncGeneratorFunction对象
  • ArrayBuffer:用于表示通用的,固定长度的原始二进制数据缓冲区
  • SharedArrayBuffer:类似于ArrayBuffer,区别是,它不能被转移
  • DataView:视图对象,它是从ArrayBuffer中读写多种数值类型的底层接口
  • Proxy:用于创建一个对象的代理,从而实现基本操作的拦截和自定义
  • 集合:支持在单个变量名下存储多个元素,js数组中每个元素可以表示所有数据类型
  • 键值对:Map、Set、WeakMap、WeakSet
  • 错误:当运行时错误产生时,错误对象会被抛出
  1. 非构造函数对象
  • eval():计算js字符串,并把它作为js代码来执行
  • isFinite():检查其参数是否是无穷大
  • isNaN():检查其参数是否是非数字值
  • parseFloat():解析一个字符串,并返回一个浮点数
  • parseInt():解析一个字符串,并返回一个整数
  • decodeURI():对encodeURI()函数编码过的URI进行解码
  • decodeURIComponent():对encodeURIComponent()函数编码的URI进行解码
  • encodeURI():把字符串作为URI进行编码
  • encodeURIComponent():把字符串作为URI进行编码,与 encodeURI() 相比,此函数会编码更多的字符

非函数对象

  • Math:拥有一些数学常数属性和数学函数方法
  • JSON:操作JSON对象
  • Atomics:提供了一组静态方法对sharedArrayBuffer和ArrayBuffer对象进行原子操作
  • Reflect:提供拦截JS操作的方法,这些方法与proxy相同
  • Intl:是ES国际化API的命名空间
  • WebAssembly: 所有webAssembly(一种新的编码方式)相关功能的命名空间

类型转换

JS是一个弱类型语言,这意味着你经常可以使用与预期类型不同类型的值,为此,JS定义了隐式类型转换规则和强制类型转换规则,隐式转换就是不需要人为控制的(语言为你自动转换为正确的类型),这种转换是临时的,并不会对原数据造成影响,而强制转换是通过方法代码控制的。不管是隐式转换还是强制转换,它们转换的结果是一致的,实际上,隐式转换底层也是强制转换实现的,即调用函数进行了转换。

隐式转换举例:+、-、*、/、%运算时,三目运算符中、循环语句中、[for...in]循环的object参数、Array方法的this值、Object方法的参数(如Object.keys())、访问基本类型的属性时。

强制转换举例:调用Number()、String()、Boolean()函数时。

转换为number

  • 对于 Number 则总是返回自己
  • undefined 变成了 NaN
  • null 变成了 0
  • true 变成了 1;false 变成了 0
  • 字符串通过解析来转换。如果解析失败,返回的结果为 NaN
  • BigInt 抛出 TypeError,以防止意外的强制隐式转换损失精度
  • Symbol 抛出 TypeError
  • 对象首先按顺序调用 [@@toPrimitive]()(hint为"number" )、valueOf() 和 toString() 方法将其转换为原始值。然后将生成的原始值转换为数值

转换为string

  • 字符串按原样返回
  • undefined 转换成 "undefined"
  • null 转换成 "null"
  • true 转换成 "true";false 转换成 "false"
  • 使用与 toString(10) 相同的算法转换数字
  • 使用与 toString(10) 相同的算法转换 BigInt
  • Symbol 抛出 TypeError
  • 对象通过依次调用 [@@toPrimitive]()(hint 为 "string")、toString() 和 valueOf() 方法将其转换为原始值。然后将生成的原始值转换为一个字符串

转换为boolean

除了null、undefined、''、0、NaN、false外,其他所有数据判定结果都为true。

转换为Symbol

  • 尝试将一个 symbol 值转换为一个 number 值时,会抛出一个 TypeError 错误 (e.g. +sym or sym | 0)
  • 使用宽松相等时,Object(sym) == sym 返回 true
  • 这会阻止你从一个 symbol 值隐式地创建一个新的 string 类型的属性名。例如,Symbol("foo") + "bar" 将抛出一个 TypeError (can't convert symbol to string)
  • "safer" String(sym) conversion 的作用会像 symbol 类型调用 Symbol.prototype.toString() 一样,但是注意 new String(sym) 将抛出异常

转换为object

  • 对象则按原样返回
  • undefined 和 null 则抛出 TypeError
  • Number、String、Boolean、Symbol、BigInt 等基本类型被封装成其对应的基本类型对象

数据声明

JS中数据的声明有四种:变量声明、函数声明、类声明、模块声明。此外,JS中只有函数有修饰符,这样的修饰符有两个,即*和async/await。

变量声明

声明变量有三种方式:var、let、const。

  1. var:声明一个函数范围或全局范围的变量
  2. let:声明可重新赋值的块级作用域局部变量
  3. const:声明不可重新赋值或声明的块级作用域局部变量

函数声明

声明函数有三种方式:普通声明、函数表达式,箭头函数。

  1. function fn() {}
  2. const fn = function() {}
  3. const fun = () => {}

函数修饰符有两种:*、async/await,比如下面这些:

  • async function
  • function*
  • async function*
  • ......

类声明

声明类方式有一种:class,类没有修饰符。

模块声明

模块的声明方式有导出(export)和导入(import),导出方式分为具名导出、默认导出,导入方式分为具名导入、默认导入、动态导入。

export

  • 具名导出:导出单个变量(export const a = x)、导出单个函数(export function a(){})、导出多个数据(export {a,b,c})
  • 默认导出:export default abc

import

  • 具名导入:import {a,b,c} from 'abc'

  • 默认导入:import abc from 'abc'

  • 动态导入:用到操作符import()

总结

本文几乎列出了所有关于数据表达的知识结构,但并未详细介绍细节。

在数据类型这块,有很多对象是日常开发几乎用不到的,其中包括一些构造函数对象和非函数对象。

新增的两种基本数据类型(Symbol和BigInt)在实际开发中几乎用不到。

相关推荐
CoderLiu9 分钟前
用这个MCP,只给大模型一个figma链接就能直接导出图片,还能自动压缩上传?
前端·llm·mcp
伍哥的传说11 分钟前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
海的诗篇_1 小时前
前端开发面试题总结-原生小程序部分
前端·javascript·面试·小程序·vue·html
uncleTom6661 小时前
前端地图可视化的新宠儿:Cesium 地图封装实践
前端
lemonzoey1 小时前
无缝集成 gemini-cli 的 vscode 插件:shenma
前端·人工智能
老家的回忆1 小时前
jsPDF和html2canvas生成pdf,组件用的elementplus,亲测30多页,20s实现
前端·vue.js·pdf·html2canvas·jspdf
半点寒12W1 小时前
uniapp全局状态管理实现方案
前端
Vertira1 小时前
pdf 合并 python实现(已解决)
前端·python·pdf
PeterJXL2 小时前
Chrome 下载文件时总是提示“已阻止不安全的下载”的解决方案
前端·chrome·安全
hackchen2 小时前
从0到1解锁Element-Plus组件二次封装El-Dialog动态调用
前端·vue.js·elementui