跳到主要内容

JS 数据类型

JavaScript 中共有七种内置数据类型,包括基本类型和对象类型。

类型

基本类型 Primitive 6 个

  • string 字符串
  • boolean 布尔值
  • number数字
  • symbol 符号
  • null 空值
  • undefined 未定义

原始类型存储的都是值,没有方法可以调用。 注意区分 string 和 String,后者表示 String 对象,有内置方法可以调用。 string 类型是不可变的,无论你在 string 类型上调用何种方法,都不会对值有改变。

另外对于 null 来说,很多人会认为他是个对象类型,其实这是错误的。虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。

面试题 原始类型有哪几种?null 是对象嘛?

对象 Object 类型

在 JS 中,除了原始类型那么其他的都是对象类型了。对象类型和原始类型不同的是,原始类型存储的是值,对象类型存储的是地址(指针)。

对象类型也叫引用类型,array 和 function 是对象的子类型。

RegExp、Date

面试题 象类型和原始类型的不同之处?函数参数是对象会发生什么问题?

类型转换

在 JS 中进行类型转换有 3 种情况,分别是

  • 转换为 boolean
  • 转换为 number
  • 转换为 string

ToPrimitive

ToPrimitive 用来将对象转换成原始类型。

第一个参数是要转换的对象,第二个可选参数是期望转换的类型。

type 为string:

  • 先调用对象的 toString 方法,如果为原始值,则return,否则进行第 2 步
  • 调用obj的valueOf方法,如果为原始值,则return,否则进行第 3 步
  • 抛出TypeError 异常

type 为number:

  • 先调用对象的 valueOf 方法,如果为原始值,则return,否则进行第 2 步
  • 调用obj的toString方法,如果为原始值,则return,否则第 3 步
  • 抛出TypeError 异常

type 参数为空:

  • 该对象为Date,则 type 被设置为String
  • 否则,type 被设置为 Number

可以重写对象 Symbol.toPrimitive 方法,该方法在转原始类型时调用优先级最高。

let a = {
valueOf() {
return 0
},
toString() {
return '1'
},
[Symbol.toPrimitive]() {
return 2
}
}
1 + a // => 3

Object.prototype.toString()

toString()方法返回一个表示该对象的字符串。

每个对象都有一个 toString() 方法,当对象被表示为文本值时或者当以期望字符串的方式引用对象时,该方法被自动调用。

Object.prototype.valueOf()

Object.prototype.valueOf()方法返回指定对象的原始值。 JavaScript 调用 valueOf() 方法用来把对象转换成原始类型的值(数值、字符串和布尔值)。但是我们很少需要自己调用此函数,valueOf 方法一般都会被 JavaScript 自动调用。

不同内置对象的valueOf实现:

  • String => 返回字符串值
  • Number => 返回数字值
  • Date => 返回一个数字,即时间值,字符串中内容是依赖于具体实现的
  • Boolean => 返回 Boolean 的 this 值
  • Object => 返回 this

Boolean

在条件判断时,除了 undefined, null, false, NaN, '', 0, -0,其他所有值都转为 true,包括所有对象。

Number

String

类型判断

typeof

typeof 对于原始类型来说,除了 null 都可以显示正确的类型

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'

typeof 对于对象来说,除了函数都会显示 object,所以说 typeof 并不能准确判断变量到底是什么类型

typeof [] // 'object'
typeof {} // 'object'
typeof /a/g // 'object'
typeof console.log // 'function'

判断是否是数组

判断是否含有某类型的方法

比如判断是否具有数组的 slice 方法。因为可以给对象添加自定义的方法,这种判断方式可能会失效。

用 obj instanceof Array

某些 IE 版本中不正确

面试题 typeof 是否能正确判断类型? instanceof 能正确判断对象的原理是什么?

示例

typeof null // object
typeof isNaN // function
typeof [] // object
toString.call([]) // [object Array]
toString.apply([], [1,2,3]) // [object Array]
[].constructor // Array

例子

实现 type 方法

function type (val) {
return typeof val !== 'object'? typeof val : Object.prototype.toString.call(val).slice(8,-1).toLowerCase();
}

常见面试题

  • 说说你对 javascript 是弱类型语言的理解?
  • javascript中强制类型转换是一个非常易出现bug的点,知道强制转换时候的规则吗?

参考