来翻一翻Javascript的数据类型。

每种编程语言都需要支持不同的数据类型,通常来说数据类型越丰富,这种编程语言就越方便使用。但是不管该编程语言中预置了多少的数据类型,在实际使用的时候往往还是不够,所以高级的编程语言都会提供一种机制,可以允许使用者自定义数据类型。

JavaScript也不例外,它提供了许多基础数据类型(Primitive Data Types),同时也提供一种构造对象(Object)的机制,提供自定义功能,可以把基础数据类型组合成更复杂的数据类型。事实上,除了基础数据类型之外,JavaScript预置了一些数据类型也是通过对象数据类型演化出来的,比如数组(Array)和日期(Date)等等。

JavaScript的数据类型

在浏览器的Web Console里面运行下面的例子:

console.log(typeof 100 === "number")
console.log(typeof Number(100) === "number")
console.log(typeof true === "boolean")
console.log(typeof Boolean(0) === "boolean")
console.log(typeof "hi"  === "string")
console.log(typeof String("yes") === "string")
console.log(typeof Symbol() === "symbol")
console.log(typeof undefined === "undefined")
console.log(typeof /12/ === "object")
console.log(typeof null === "object")
console.log(typeof [] === "object")
console.log(typeof {} === "object")

上面每一行都打印输出true。

JavaScript的基础数据类型有这下面几种:

  • number
  • boolean
  • string
  • undefined
  • symbol (ES6新增的数据类型)

对于所有的对象数据类型,使用typeof得到的结果都是

  • object

基础数据类型的对象化

基础数据类型存在一些使用上的不便,因为它们不像对象类型那样可以有方法和属性。Javascript对此的应对之法是对于某个特定的基础数据类型,制造出一个与之对应的对象类型:

  • 基础类型 => 对象类型
  • boolean => Boolean
  • number => Number
  • string => String

基础类型全部都是小写字母开头的,与其对应的对象数据类型则是首字母大写开头的

所有的对象类型都是用new关键字创建的:

console.log(typeof(Boolean("I'm true"))) // 输出 boolean
console.log(typeof(new Boolean("I'm true"))) // 输出 object
console.log(typeof(Number(100))) // 输出 number
console.log(typeof(new Number(100))) // 输出 object
console.log(typeof(String("sweetie!"))) // 输出 string
console.log(typeof(new String("heart"))) // 输出 object

对于其他两种基础数据类型:

  • undefined
  • symbol

undefined的功能比较单一,它不需要属性和方法,所以不需要对象化。symbol数据类型是ES6版本新加的,它比较特殊,虽然有属性和方法,但是它不能用new关键字来构造对象。如果执行new Symbol(1),Javascript解释器会告诉你TypeError: Symbol is not a constructor

对象化的好处

基础类型对象化了之后,就有了属性和方法,就有了诸多好处。

比如下面这个关于number的例子:

var n = 1.31415
console.log(typeof(n)) // number
console.log(n.toString()) // "1.31415"
console.log(n.__proto__) // Number {constructor: ƒ, …}

n的数据类型是number,这是一个基础数据类型,本来没有属性和方法。但是在需要的情况下,比如n.toString()n.__proto__,Javascript会自动把n从基础数据类型转化为对象类型,于是乎n就有了方法toString()和属性__proto__

对于string类型,情况类似:

var s = "hi"
console.log(typeof(n)) // string
console.log(s.length) // 2
console.log(s.__proto__) // String {length: 0, constructor: ƒ, …}

javascript还支持直接从string的字面值直接调用String对象的方法和属性:

console.log("hello".length) // 5
console.log("hello".__proto__) // String {length: 0, constructor: ƒ, …}

“hello"是一个字面值,在需要的时候javascript会将其转化为一个String对象,并调用相应的方法。

对于boolean而言,它所对应的Boolean对象的主要功能是充当一个转换器,把其他值转化为布尔值:

console.log(new Boolean()) // false
console.log(new Boolean(0)) // false
console.log(new Boolean(null)) // false
console.log(new Boolean('')) // false
console.log(new Boolean(false)) // false
console.log(new Boolean(1)) 
console.log(new Boolean("hi"))
console.log(new Boolean([])) 
console.log(new Boolean({})) 
console.log(new Boolean(true)) 

A JavaScript object is a mapping between keys and values. Keys are strings (or Symbols) and values can be anything.

其他参考

(未完待续)