当前位置: 首页 > news >正文

JavaScript数据类型

数据类型

6种简单数据类型:Undefined、Null、Boolean、Number、String、Symbol。引用数据类型:Object(无序名称对的集合)。

1)typeof操作符

typeof后面直接跟变量或数值字面量,因为typeof是一个操作符而不是函数,所以不需要参数(但可以使用参数)。

注意typeof在某些情况下返回的结果可能会让人费解,但技术上讲还是正确的。比如,调用typeof null返回的是"object"。这是因为特殊值null被认为是一个对空对象的引用。

注意 严格来讲,函数在ECMAScript中被认为是对象,并不代表一种数据类型。可是,函数也有自己特殊的属性。为此,就有必要通过typeof操作符来区分函数和其他对象。

2)Undefined类型

Undefined类型只有一个值,就是特殊值undefined。

当使用var或let声明了变量但没有初始化时,就相当于给变量赋予了undefined值。

注意:一般来说,永远不用显示地给某个变量设置undefined值。字面值undefined主要用于比较。增加这个特殊值的目的就是为了正式明确空对象指针(null)和未初始化变量的区别。

3)Null类型

Null类型同样只有一个值,即特殊值null。逻辑上讲,null值表示一个空对象指针,这也是给typeof传一个null会返回"object"的原因。

在定义将来要保存对象值的变量时,建议使用null来初始化,不要使用其他值。这样,只要检查这个变量的值是不是null就可以知道这个变量是否在后来被重新赋予了一个对象的引用。

undefinded是由null值派生而来,因此它们表面上相等。用等于操作符(==)比较null和undefined始终返回true。但要注意,这个操作符会为了比较而转换它的操作数。

即使null和undefined有关系,它们的用途也是完全不一样的。永远不必显式地将变量值设置为undefined。但null不是这样的。任何时候,只要变量要保存对象,而当时又没有那个对象可保存,就要用null来填充该变量。

4)Boolean类型

Boolean(布尔值)类型是ECMAScript中使用最频繁的类型之一,有两个字面值:true和false。这两个布尔值不同于数值,因此true不等于1,false不等于0。

注意,布尔值字面量true和false是区分大小写的,因此True和False(及其他大小混写形式)是有效的标识符,但不是布尔值。

Boolean()转型函数可以在任意类型的数据上调用,而且始终返回一个布尔值。什么值能转换为true或false的规则取决于数据类型和实际的值。

理解以上转换非常重要,因为像if等流控制语句会自动执行其他类型值到布尔值的转换。

5)Number类型

最基本的数值字面量格式是十进制整数,直接写出来即可。

对于八进制字面量,第一个数字必须是零(0),然后是相应的八进制数字(数值0~7)。如果字面量中包含的数字超出了应有的范围,就会忽略前缀的零,后面的数字序列会被当成十进制数。

十六进制字面量,必须先写前缀0x(区分大小写),然后是十六进制数字(09以及AF)。十六进制数字中的字母大小写均可。

①浮点值
要定义浮点值,数值中必须包含小数点,而且小数点后面必须至少有一个数字。虽然小数点前面不是必须有整数,但推荐加上。

因为存储浮点值使用的内存空间是存储整数值的两倍,所以ECMAScript总是想方设法把值转换为整数。在小数点后面没有数字的情况下,数值就会变成整数。类似地,如果数值本身就是整数,只是小数点后面跟着0(如1.0),那它也会被转换为整数。

ECMAScript中科学记数法的格式要求是一个数值(整数或浮点数)后跟一个大写或小写的字母e,再加上一个要乘的10的多少次幂。

浮点值的精确度最高可达17位小数,但在算术计算中远不如整数精确。例如0.1加0.2得到的不是0.3,因此永远不要测试某个特定的浮点值。

②值的范围

ECMAScript可以表示的最小数值保存在Number.MIN_VALUE中,这个值在多数浏览器中是5e-324;可以表示的最大数值保存在Number.MAX_VALUE中,这个值在多数浏览器中是1.797693134862315 7e+308。

如果某个计算得到的数值结果超出了JavaScript可以表示的范围,那么这个数值会被自动转换为一个特殊的Infinity(无穷)值。任何无法表示的负数以-Infinity(负无穷大)表示,任何无法表示的正数以Infinity(正无穷大)表示。

如果计算返回正Infinity或负Infinity,则该值将不能再进一步用于任何计算。这是因为Infinity没有可用于计算的数值表示形式。

要确定一个值是不是有限大(即介于JavaScript能表示的最小值和最大值之间),可以使用isFinite()函数。

注意 使用Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY也可以获取正、负Infinity。没错,这两个属性包含的值分别就是-Infinity和Infinity。

③NaN

有一个特殊的数值叫NaN,意思是“不是数值”(Not a Number),用于表示本来要返回数值的操作失败了(而不是抛出错误)。比如,用0除任意数值在其他语言中通常都会导致错误,从而中止代码执行。但在ECMAScript中,0、+0或-0相除会返回NaN。

如果分子是非0值,分母是有符号0或无符号0,则会返回Infinity或-Infinity。

NaN有几个独特的属性。首先,任何涉及NaN的操作始终返回NaN(如NaN/10),在连续多步计算时这可能是个问题。

NaN不等于包括NaN在内的任何值。

ECMAScript提供了isNaN()函数。该函数接收一个参数,可以是任意数据类型,然后判断这个参数是否“不是数值”。把一个值传给isNaN()后,该函数会尝试把它转换为数值。某些非数值的值可以直接转换成数值,如字符串"10"或布尔值。任何不能转换为数值的值都会导致这个函数返回true。

④数值转换

有3个函数可以将非数值转换为数值:Number()、parseInt()和parseFloat()。

Number()是转型函数,可用于任何数据类型。后两个函数主要用于将字符串转换为数值。

Number()函数基于如下规则执行转换。

  • 布尔值,true转换为1,false转换为0。

  • 数值,直接返回。

  • null,返回0。

  • undefined,返回NaN。

    字符串,应用以下规则。

  • 如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此,Number(“1”)返回1,Number(“123”)返回123,Number(“011”)返回11(忽略前面的零)。

  • 如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值(同样,忽略前面的零)。

  • 如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整数值。

  • 如果是空字符串(不包含字符),则返回0。

  • 如果字符串包含除上述情况之外的其他字符,则返回NaN。

  • 对象,调用valueOf()方法,并按照上述规则转换返回的值。如果转换结果是NaN,则调用toString()方法,再按照转换字符串的规则转换。

考虑到用Number()函数转换字符串时相对复杂且有点反常规,通常在需要得到整数时可以优先使用parseInt()函数。

parseInt()函数更专注于字符串是否包含数值模式。字符串最前面的空格会被忽略,从第一个非空格字符开始转换。

如果第一个字符不是数值字符、加号或减号,parseInt()立即返回NaN。这意味着空字符串也会返回NaN(这一点跟Number()不一样,它返回0)。

如果第一个字符是数值字符、加号或减号,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符。比如,"1234blue"会被转换为1234,因为"blue"会被完全忽略。类似地,"22.5"会被转换为22,因为小数点不是有效的整数字符。

假设字符串中的第一个字符是数值字符,parseInt()函数也能识别不同的整数格式(十进制、八进制、十六进制)。
换句话说,如果字符串以"0x"开头,就会被解释为十六进制整数。如果字符串以"0"开头,且紧跟着数值字符,在非严格模式下会被某些实现解释为八进制整数。

不同的数值格式很容易混淆,因此parseInt()也接收第二个参数,用于指定底数(进制数)。

如果知道要解析的值是十六进制,那么可以传入16作为第二个参数,以便正确解析。

let num = parseInt("0xAF", 16);   // 175

实际上,如果提供了十六进制参数,那么字符串前面的"0x"可以省掉。

let num1 = parseInt("AF", 16);   // 175
let num2 = parseInt("AF");    // NaN

parseFloat()函数的工作方式跟parseInt()函数类似,都是从位置0开始检测每个字符。同样,它也是解析到字符串末尾或者解析到一个无效的浮点数值字符为止。这意味着第一次出现的小数点是有效的,但第二次出现的小数点就无效了,此时字符串的剩余字符都会被忽略。因此,"22.34.5"将转换成22.34。

parseFloat()函数的另一个不同之处在于,它始终忽略字符串开头的零。这个函数能识别前面讨论的所有浮点格式,以及十进制格式(开头的零始终被忽略)。十六进制数值始终会返回0。因为parseFloat()只解析十进制值,因此不能指定底数。最后,如果字符串表示整数(没有小数点或者小数点后面只有一个零),则parseFloat()返回整数。

6)String类型

String(字符串)数据类型表示零或多个16位Unicode字符序列。字符串可以使用双引号(")、单引号(')或反引号(`)标示。

①字符字面量

字符串数据类型包含一些字符字面量,用于表示非打印字符或有其他用途的字符。

字符串的长度可通过其length属性获取。

②字符串的特点

ECMAScript中的字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量。

③转换为字符串

有两种方式把一个值转换为字符串。首先是使用几乎所有值都有的toString()方法。

这个方法唯一的用途就是返回当前值的字符串等价物。

toString()方法可见于数值、布尔值、对象和字符串值。(没错,字符串值也有toString()方法,该方法只是简单地返回自身的一个副本。)

null和undefined值没有toString()方法。

多数情况下,toString()不接收任何参数。不过,在对数值调用这个方法时,toString()可以接收一个底数参数,即以什么底数来输出数值的字符串表示。默认情况下,toString()返回数值的十进制字符串表示。而通过传入参数,可以得到数值的二进制、八进制、十六进制,或者其他任何有效基数的字符串表示。

如果你不确定一个值是不是null或undefined,可以使用String()转型函数,它始终会返回表示相应类型值的字符串。String()函数遵循如下规则。

  • 如果值有toString()方法,则调用该方法(不传参数)并返回结果。
  • 如果值是null,返回"null"。
  • 如果值是undefined,返回"undefined"。

注意 用加号操作符给一个值加上一个空字符串""也可以将其转换为字符串。

④模板字面量

ECMAScript 6新增了使用模板字面量定义字符串的能力。与使用单引号或双引号不同,模板字面量保留换行字符,可以跨行定义字符串。

⑤字符串插值

模板字面量最常用的一个特性是支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。

技术上讲,模板字面量不是字符串,而是一种特殊的JavaScript句法表达式,只不过求值后得到的是字符串。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。

字符串插值通过在${}中使用一个JavaScript表达式实现。

7)Symbol类型

Symbol(符号)是ECMAScript 6新增的数据类型。符号是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。

尽管听起来跟私有属性有点类似,但符号并不是为了提供私有属性的行为才增加的(尤其是因为Object API提供了方法,可以更方便地发现符号属性)。相反,符号就是用来创建唯一记号,进而用作非字符串形式的对象属性。

①符号的基本用法

符号需要使用Symbol()函数初始化。因为符号本身是原始类型,所以typeof操作符对符号返回symbol。

let sym = Symbol();
console.log(typeof sym);   // Symbol

调用Symbol()函数时,也可以传入一个字符串参数作为对符号的描述(description),将来可以通过这个字符串来调试代码。但是,这个字符串参数与符号定义或标识完全无关。

符号没有字面量语法,这也是它们发挥作用的关键。按照规范,你只要创建Symbol()实例并将其用作对象的新属性,就可以保证它不会覆盖已有的对象属性,无论是符号属性还是字符串属性。

最重要的是,Symbol()函数不能与new关键字一起作为构造函数使用。这样做是为了避免创建符号包装对象,像使用Boolean、String或Number那样,它们都支持构造函数且可用于初始化包含原始值的包装对象。

如果你确实想使用符号包装对象,可以借用Object()函数。

let mySymbol = Symbol();
let myWrappedSymbol = Object(mySymbol);
console.log(typeof myWrappedSymbol);    // "object"

②使用全局符号注册表

如果运行时的不同部分需要共享和重用符号实例,那么可以用一个字符串作为键,在全局符号注册表中创建并重用符号,为此,需要使用Symbol.for()方法。

Symbol.for()对每个字符串键都执行幂等操作。第一次使用某个字符串调用时,它会检查全局运行时注册表,发现不存在对应的符号,于是就会生成一个新符号实例并添加到注册表中。后续使用相同字符串的调用同样会检查注册表,发现存在与该字符串对应的符号,然后就会返回该符号实例。

即使采用相同的符号描述,在全局注册表中定义的符号跟使用Symbol()定义的符号也并不等同。

全局注册表中的符号必须使用字符串键来创建,因此作为参数传给Symbol.for()的任何值都会被转换为字符串。此外,注册表中使用的键同时也会被用作符号描述。

let emptyGlobalSymbol = Symbol.for();
console.log(emptyGlobalSymbol);     // Symbol(undefined)

还可以使用Symbol.keyFor()来查询全局注册表,这个方法接收符号,返回该全局符号对应的字符串键。如果查询的不是全局符号,则返回undefined。

// 创建全局符号
let s = Symbol.for('foo');
console.log(Symbol.keyFor(s));    // foo
// 创建普通符号
let s2 = Symbol('bar');
console.log(Symbol.keyFor(s2));   // undefined

如果传给Symbol.keyFor()的不是符号,则该方法抛出TypeError。

③使用符号作为属性

凡是可以使用字符串或数值作为属性的地方,都可以使用符号。这就包括了对象字面量属性和Object.defineProperty()/Object.defineProperties()定义的属性。对象字面量只能在计算属性语法中使用符号作为属性。

8)Object类型

ECMAScript中的对象其实就是一组数据和功能的集合。对象通过new操作符后跟对象类型的名称来创建。

http://www.dtcms.com/a/305796.html

相关文章:

  • 高密度客流特征识别误差↓76%!陌讯多模态轻量化算法实战解析
  • Linux初始及常见指令使用
  • Redis学习------缓存雪崩
  • 解决Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required报错问题
  • 视频生成模型蒸馏的方法
  • Orange的运维学习日记--19.Linux文件归档和备份
  • 15.10 单机8卡到千卡集群!DeepSpeed实战调参手册:A100训练效率翻倍,百万成本优化实录
  • 南水北调东线工程图件 shp数据
  • 三目云台全景监控画面实现三个画面联动
  • 【图像处理】直方图均衡化c++实现
  • python基础语法2,程序控制语句(简单易上手的python语法教学)(课后练习题)
  • Python3与MySQL的PyMySQL连接与应用
  • 【Spring Boot 快速入门】四、MyBatis
  • Nestjs框架: 关于 OOP / FP / FRP 编程
  • 关于神经网络CNN的搭建过程以及图像卷积的实现过程学习
  • OSS-服务端签名Web端直传+STS获取临时凭证+POST签名v4版本开发过程中的细节
  • 修改Windows鼠标滚轮方向
  • 《计算机组成原理与汇编语言程序设计》实验报告六 存储器实验
  • mangoDB面试题及详细答案 117道(071-095)
  • LeetCode 160:相交链表
  • 使用es实现全文检索并且高亮显示
  • 利用SQL文件上传注入植入WebShell
  • Linux->动静态库
  • UniSeg3D:A Unified Framework for 3D Scene Understanding
  • 如何读懂 火山方舟 API 部分的内容
  • yolo8+阿里千问图片理解(华为简易版小艺看世界)
  • PostgreSQL 与 Oracle 数据库字段类型的详细对比
  • CSS 工作原理
  • Qt知识点2『Ubuntu24.04.2安装Qt5.12.9各种报错』
  • git报failed to connect to github.com port 443 after 21064