数据类型
记录些关于 JavaScript 数据类型的知识点
note
JavaScript 中的数据类型分为基本类型和引言类型。其中,基本类型包括 Null
、Undefined
、Boolean
、String
、Symbol
和 BigInt
;引用类型指的是 Object
。
null
和 undefined
的区别?#
1️⃣ #
定义Javascript
中,null
是一个表示“无”的对象,转为数值时为 0;undefined
是一个表示“无”的原始值,转为数值时为 NaN。
#
应用null 表示"没有对象",即该处不应该有值。典型用法是:
1、作为函数的参数,表示该函数的参数不是对象。
2、作为对象原型链的终点。
undefined 表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:
1、变量被声明了,但是未被赋值,此时为 undefined
。
2、调用函数时,应该提供的参数没有提供,该参数等于 undefined
。
3、对象没有被赋值的属性,该属性的值为 undefined
。
4、函数没有返回值时,默认值为 undefined
。
#
2️⃣ 判空应该注意什么?JavaScript 中有 5 种空值和假值,分别是 undefined、null、false、""、0。
逻辑或操作符 (||
)会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 ||
来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,''
或 0
)时
空值合并操作符(??
)是一个逻辑操作符,当左侧的操作数为 null
或者 undefined
时,返回其右侧操作数,否则返回左侧操作数。
#
3️⃣ BigInt
BigInt
是一种内置对象,它提供了一种方法来表示大于 2^53 - 1 的整数。这原本是 Javascript中可以用 Number 表示的最大数字。BigInt 可以表示任意大的整数。
BigInt
在某些方面类似于 Number
,但是也有几个关键的不同点:不能用于 Math
对象中的方法;不能和任何 Number
实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt
变量在转换成 Number
变量时可能会丢失精度。
Symbol#
4️⃣Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"。
每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。
需要注意的是通过 Symbol 方法创建值的时候不用使用 new 操作符,原因是通过 new 实例化的结果是一个 object 对象,而不是原始类型的 symbol
#
应用场景- 定义常量,消除与业务无关的字符
- 作为对象属性,避免多属性的复杂对象中,容易覆盖属性名的问题。
- 模拟类的私有方法
ES6 中的类是没有 private 关键字来声明类的私有方法和私有变量的,但是可以利用 Symbol 的唯一性来模拟。
#
5️⃣ 如何判断数据类型?typeof#
typeof
只能判断出基本类型和引用类型,其中有两个需要注意的情况:
- typeof NaN
ECMAScript标准指出,数字应为IEEE-754浮点数据。这包括Infinity,-Infinity和NaN。
根据定义,NaN是具有不确定数值结果的运算的返回值。因此,在JavaScript中,NaN
除了成为全局对象的一部分之外,还成为 Number
对象的一部分:Number.NaN
。NaN
仍然是数字数据类型,但未定义为实数。
- typeof null
JavaScript 类型值是存在32 bit 单元里,32位有1-3位表示TYPE TAG,其它位表示真实值。而表示object的标记位正好是低三位都是0。
1:整型(int)
000:引用类型(object)
010:双精度浮点型(double)
100:字符串(string)
110:布尔型(boolean)
但有两个特殊值:
- undefined,用整数−2^30(负2的30次方,不在整型的范围内)
- null,机器码空指针(C/C++ 宏定义),低三位也是000
由于 null
代表的是空指针(低三位也是 000
),因此,null
的类型标签是 000
,typeof null
也因此返回 "object"。
instanceof#
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
note
需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 proto 伪属性,是可以实现的。比如执行 obj.proto = {} 之后,obj instanceof Foo 就会返回 false 了。
instanceof
的实现原理是:右侧构造函数的 prototype
属性在左侧实例对象的原型链上则返回 true
,否则返回 false
。因此, instanceof
在查找过程中会遍历左侧实例对象的原型链。简单实现如下: