各种对象上的 toString 方法的区别和关联
问:请简述一下用于判断数据类型都有哪些方法?
答:巴拉巴拉……小魔仙
在判断数据类型的时候,有一种方式可以清晰直接地区分出所有的数据类型,即 Object.prototype.toString.call()
,这方法的核心就是利用了 Object
的原型对象上的 toString
方法,这个方法会返回一个表示对象的字符串,返回的格式是 [object type]
,其中的 type
指代的是具体的数据类型,如下示例代码所示:
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(0) // "[object Number]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(new Date()) // "[object Date]"
Object.prototype.toString.call(new Error()) // "[object Error]"
Object.prototype.toString.call(() => {}) // "[object Function]"
Object.prototype.toString.call(Symbol('s')) // "[object Symbol]"
Object.prototype.toString.call(new Promise((resolved) => {resolved()})) // "[object Promise]"
Object.prototype.toString.call(new Set([1, 2])) // "[object Set]"
Object.prototype.toString.call(new Map([['a', 1]])) // "[object Map]"
Object.prototype.toString.call(new ArrayBuffer()) // "[object ArrayBuffer]"
Object.prototype.toString.call(/1/) // "[object RegExp]"
class C {}
Object.prototype.toString.call(C) // "[object Function]"
Object.prototype.toString.call(new C()) // "[object Object]"
除了 Object.prototype
上有 toString
方法外,Date
、Array
、Number
、String
、Boolean
、Function
、Error
这些对象上面的原型对象上实际上也都存在自己的 toString
方法,而这些自有的方法的作用却不一而同,如下:
-
Date.prototype.toString() 方法返回一个表示指定日期对象的字符串。
new Date().toString() // "Tue Mar 08 2022 16:05:08 GMT+0800 (中国标准时间)"
-
Array.prototype.toString() 方法返回一个表示指定数组及其元素的字符串。作用等同于使用不传参的 join 方法,但这两个方法都不能对包含 Symbol 类型的值的数据进行转换
[1, '2', true, undefined, null, {}, [], () => 1].toString() // "1,2,true,,,[object Object],,() => 1" [1, '2', true, undefined, null, {}, [], () => 1].join() // "1,2,true,,,[object Object],,() => 1" [1, '2', true, undefined, null, {}, [], () => 1, Symbol('1')].toString() // Uncaught TypeError: Cannot convert a Symbol value to a string // 需要注意的是,如果子项是数组,无论是一层还是多层,都会被展开,如: [1, [2, [3, [4]]]].toString() // "1,2,3,4"
-
Number.prototype.toString(radix) 方法返回一个表示指定数字对象的字符串,入参 radix 表示范围从2到36的整数,指定用于表示数值的基数
(1).toString() // "1" (-1.2222).toString() // "-1.2222" (Infinity).toString() // "Infinity" (6).toString(2) // "110"
-
String.prototype.toString() 方法返回一个表示指定对象的字符串。
'str'.toString() // "str"
-
Boolean.prototype.toString() 方法返回一个表示指定布尔对象的字符串。
(true).toString() // "true" (false).toString() // "false"
-
Function.prototype.toString() 方法返回一个表示方法源码的字符串。更多详细的对比实际源码和
toString
转换结果的示例详见 MDN Examples(() => {}).toString() // "() => {}" (function func() {}).toString() // "function func() {}"
-
Error.prototype.toString() 方法返回一个表示指定异常对象的字符串。
new Error('error').toString() // "Error: error"
此外,还有 URL.toString()、URLSearchParams.toString()、RegExp.prototype.toString() 和 Symbol.prototype.toString() 这四个方法分别有自己的实现,这里就不一一写明了,可以点击链接查看 MDN 介绍。
由上,关于 toString
方法可以分为三类,一类是像 Date
、Array
、Number
、String
、Boolean
、Function
、Error
、URL
、URLSearchParams
、RegExp
、Symbol
这些对象上重写了 toString
方法,都有自己独特的用处,另一类是像 null
、undefined
这样的数据类型是没有 toString
方法的,最后一类则是除上之外其它的对象都是调用的原型链上的 Object.prototype.toString
方法。