跳至主要內容

数据类型

Yang大约 8 分钟JavaScript

数据类型

  • 分类
    • 基本数据类型:
      • Undefined
      • Null
      • Boolean
      • Number
      • BigInt
      • String
      • Symbol
    • 复杂数据类型:
      • Object

Undefined 类型

  • Undefined 类型只有一个值,即 undefined
  • 使用 var 声明变量但未初始化时,值为 undefined
  • 对未声明的变量 typeof 时,也会返回 undefined
  • 相等性检查 == 中,undefined 只与 null 相等

Null 类型

  • Null 类型只有一个值,即 null
  • 从逻辑角度看,null 表示空对象指针
  • console.log(typeof null); // object
  • undefined 值派生自 null 值
    • console.log(null==undefined); // true
**undefined** 和 **null** 在相等性检查 `==` 中不会进行任何类型转换,除非你非常清楚自己在做什么,否则永远不要使用 >= > < <= 去比较一个可能为 `null/undefined` 的变量。对于取值可能是 `null/undefined` 的变量,请按需要分别检查它的取值情况

Boolean 类型

  • 该类型只有两个值: truefalse,并且区分大小写
  • 一个值要转化为 Boolean 值,可以调用 Boolean()

其他类型转化为布尔值的规则

数据类型转化为 true 的值转化为 false 的值
Booleantruefalse
String任何非空字符串空字符串
Number任何非零数字值(包括无穷大)0 和 NaN
Object任何对象null
Undefined不存在undefined

Number 类型

  • 使用 IEEE754 格式来表示整数和浮点数值(双精度数值)
  • 十进制
  • 八进制
    • 以 8 为基数
    • 第一位必须是 0,后面为八进制数字序列(0~7)
    • 如果字面值的数值超出范围,则前导 0 被忽略,后面的数被当做十进制数值
    • 八进制字面量在严格模式下无效,会报错
  • 十六进制
    • 以 16 为基数
    • 前两位必须是 0x,后面为十六进制数字序列(0-9 及 A~F),不区分大小写
  • 在进行算数计算时,所有的八进制和十六进制表示的数值都将被换成十进制数值
  • NaN,即非数值,是一个特殊的数值
    • 表示一个本来要返回数值的操作数未返回数值的情况(不会抛出错误)
    • 任何数值除以 0 都会返回 NaN,不会影响其它代码执行
    • 任何涉及 NaN 的操作(例如 NaN/10)都会返回 NaN
    • NaN 与任何值都不相等,包括其本身
      • console.log(NaN==Nan); // false
    • isNaN() 接受一个任意类型参数,判断这个参数是否 “不是数值”(尝试转化为数值),并返回布尔值
      • 不能被转化为数值的值返回 true
      • 能转化为数值的值返回 false
  • 注意:
    • 浮点数精度问题
      • 0.1+0.2=0.30000000000000004(不要测试某个特定的浮点数值)
    • 数值范围
      • 最小数值 Number.MIN_VALUE,大多数浏览器中,这个值是 5e-324
      • 最大数值 Number.MAX_VALUE,大多数浏览器中,这个值是 1.7976931348623157e+308
      • 如果计算超出了这个数值范围,这个数值将被自动转换成特殊的 Infinity 值
        • -Infinity 负无穷
        • Infinity 正无穷
  • 三个将非数值转化为数值的函数:Number()、parseInt()、parseFloat()

Number() 函数转换规则

  • 如果是布尔值,true 和 false 将分别被转换为 1 和 0
  • 如果是数字值,只是简单的传入和返回
  • 如果是 null 值,返回 0
  • 如果是 undefined ,返回 NaN
  • 如果是字符串,遵循下列规则
    • 如果字符串中只包含数字(包括前面带正号或符号的情况),则将其转换为十进制数值(会忽略前导 0)
    • 如果字符串包含有效的浮点格式,则将其转换为对应的浮点数值(会忽略前导 0)
    • 如果字符串包含有效的十六进制格式,则将其转换为对应的十进制整数值
    • 如果字符串是空的(不包含任何字符),则将其转换为 0
    • 如果字符串包含上述格式以外的字符,则将其转换为 NaN
    • 如果是对象,则调用对象的 valueOf() 方法,然后依照前面的规则转换反悔的值。如果转换的结果是 NaN,则调用对象的 toString() 方法,然后再次依照前面的规则转换反悔的字符串值
  • 一元加操作符的操作与 Number() 函数相同

parseInt() 函数转换规则

  • 空字符串,返回 NaN
  • 忽略字符串前的空格,直至找到第一个非空字符串
  • 如果第一个字符不是数字或者正负号,返回 NaN
  • 如果第一个字符是数字字符,则会继续解析后续字符直至遇到一个非数字字符
  • 遇到小数点也会停止,因为小数点不是有效的数字字符
  • 能识别出其他进制数字字符,转化为十进制返回
  • 八进制的字面量字符串存在分歧,可以携带第二个参数,表示转化是使用的基数(即进制)
    • console.log(parseInt("0xAF",16)); // 175 (可以省略 0x)

parseFloat() 函数转换规则

  • parseFloat() 与 parseInt() 函数类似
  • 解析过程成遇到的第一个小数点有效,第二个小数点无效
  • 只解析十进制,没有第二个参数
  • 十六进制字符串始终会被转换成 0
  • 如果字符串包含的是一个可解析为整数的数(没有小数点,或小数点后面都是 0),则函数会返回整数

String 类型

  • 两个将一个值转化为一个字符串的函数:toString()、String()

toString() 函数转换规则

  • 数值、布尔值、对象和字符串都有 toString() 方法,该方法返回字符串的一个副本
  • null 和 undefined 值没有这个方法
  • 多数情况下,toString() 方法不用传递参数
  • 调用数值的 toString() 方法时,可以传递一个参数,表示输出数值的基数(进制,默认为 10)

String() 函数转换规则

  • 在不知道要转换的值是不是 null 或 undefined 的情况下可以使用,可以将任何类型的值转换为字符串
  • 如果值有 toString() 方法,则调用该方法(没有参数)并返回相应结果
  • 如果值是 null ,则返回 “null”
  • 如果值是 undefined ,则返回 “unfined”

Object 类型

  • 一组数据和功能的集合
  • Object 类型所具有的任何属性和方法也同样存在于更具体的对象中

Object 的每个实例都具有以下属性和方法

  • Constructor:保存着用于创建当前对象的函数
  • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在
    • 作为参数的属性名(propertyName)必须以字符串形式指定
      • 例如:o.hasOwnProperty("name")
  • isPrototypeOf(object):用于检查传入的对象是否是另一个对象的原型
  • propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句来枚举。
    • 作为参数的属性名(propertyName)必须以字符串形式指定
  • toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应
  • toString():返回对象的字符串表示
  • valueOf():返回对象的字符串、数值或布尔值表示。通常与 toString() 方法的返回值相同

类型判断

typeof 操作符

是确定一个变量是 字符串、数值、布尔值还是 undefined 的最佳工具
如果值是一个对象或 null ,结果返回 object
如果值是函数,该操作符会返回 function
如果值是正则表达式,则可能返回 function 或 object (浏览器差异)

  • 语法:typeof xtypeof(x)
  • 返回变量数据类型的字符串,返回结果如下
    • undefined:值 未定义
    • boolean:值为 布尔值
    • string:值为 字符串
    • number:值为 数值
    • bigint:值为特大的数值
    • object:值为 对象或 null
    • function:值为 函数
    • symbol:值位 symbol

instanceof 操作符

  • 语法:result = variable instanceof constructor
  • 如果变量是给定引用类型(根据原型链识别)的实例则返回 true
    • 所有引用类型都是 Object 的实例,在检测一个应用类型值和 Object 构造函数时,instanceof 操作符始终会返回 true
    • 如果使用 instanceof 操作符检测基本数据类型的值,该操作符始终返回 false ,因为基本类型不是对象

比 typeof 运算符更准确的类型判断

不同数据类型的Object.prototype.toString方法返回值如下。

  • 数值:返回[object Number]
  • 字符串:返回[object String]
  • 布尔值:返回[object Boolean]
  • undefined:返回[object Undefined]
  • null:返回[object Null]
  • 数组:返回[object Array]
  • arguments 对象:返回[object Arguments]
  • 函数:返回[object Function]
  • Error 对象:返回[object Error]
  • Date 对象:返回[object Date]
  • RegExp 对象:返回[object RegExp]
  • 其他对象:返回[object Object]

这就是说,Object.prototype.toString可以看出一个值到底是什么类型。

Object.prototype.toString.call(2) // "[object Number]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(Math) // "[object Math]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"

利用这个特性,可以写出一个比typeof运算符更准确的类型判断函数。

var type = function (o) {
  var s = Object.prototype.toString.call(o)
  return s.match(/\[object (.*?)\]/)[1].toLowerCase()
}
type({}) // "object"
type([]) // "array"
type(5) // "number"
type(null) // "null"
type() // "undefined"
type(/abcd/) // "regex"
type(new Date()) // "date"

在上面这个type函数的基础上,还可以加上专门判断某种类型数据的方法。

var type = function (o) {
  var s = Object.prototype.toString.call(o)
  return s.match(/\[object (.*?)\]/)[1].toLowerCase()
}

;[
  'Null',
  'Undefined',
  'Object',
  'Array',
  'String',
  'Number',
  'Boolean',
  'Function',
  'RegExp'
].forEach(function (t) {
  type['is' + t] = function (o) {
    return type(o) === t.toLowerCase()
  }
})

type.isObject({}) // true
type.isNumber(NaN) // true
type.isRegExp(/abc/) // true
上次编辑于:
贡献者: sunzhenyang