本文详细解析 JavaScript 中的三种显式类型转换机制:ToString、ToNumber 和 ToBoolean。通过 String()、Number()、parseInt()、parseFloat() 及 Boolean() 等核心函数的规则说明,结合 JSON.stringify 的序列化行为,帮助开发者准确掌握基础类型与对象在强制转换时的具体表现及边界情况。
ToString:字符串化规则与对象处理
ToString
在 JavaScript 中,ToString 机制负责处理将非字符串值强制转换为字符串的过程。实现这一转换的常用方法包括全局函数 String() 以及对象原型的 toString() 方法。
对于基本数据类型,其字符串化遵循特定规则:
- null 值会被转换为字符串 'null'。
- undefined 值会被转换为字符串 'undefined'。
- 布尔值 true 会被转换为字符串 'true'。
- 数字类型的字符串化遵循通用规范,当数值极大或极小时,系统将采用科学计数法进行表示。
普通对象在进行字符串化时,实际执行的是 Object.prototype.toString() 方法,返回结果格式为 [object type],例如:
var test = {a : 'test'}
console.log(test.toString()) // '[object Object]'
console.log(String(test)) // '[object Object]'
然而,如果对象自定义了 toString 方法,字符串化过程将调用该方法并返回其执行结果,例如:
var obj = {
a: 'test',
toString: function () {
return 1
}
}
console.log(obj.toString()) // 1
console.log(String(obj)) // 1
数组在字符串化时,会将数组内所有元素分别转换为字符串,并使用逗号 ',' 连接各元素,例如:
var arr = [1, 2]
console.log(arr.toString()) // '1,2'
console.log(String(arr)) // '1,2'
JSON.stringify()
JSON.stringify() 函数在将 JSON 对象序列化为字符串时,同样涉及字符串化的相关规则。
对于大多数简单值而言,JSON 字符串化的效果与 toString() 基本一致,例如:
console.log(JSON.stringify("test")) // ""test""
console.log(JSON.stringify(1)) // "1"
console.log(JSON.stringify(null)) // "null"
但是,JSON.stringify() 在对象中遇到 function() {}、undefined 或 Symbol 类型时,会自动忽略这些属性;若在数组中遇到这些值,则返回 null,例如:
var obj1 = {
a: undefined,
b: function () {},
c: Symbol()
}
console.log(JSON.stringify(obj1)) // "{}"
console.log(JSON.stringify([undefined, function () {}, 1])) // "[null, mull, 1]"
当对象执行 JSON.stringify() 方法时,如果该对象存在 toJSON 方法,系统将使用 toJSON 方法的返回值来进行序列化,例如:
var obj2 = {
a: undefined,
b: function () {},
c: Symbol(),
toJSON: function () {
return {a: 'replace'}
}
}
console.log(JSON.stringify(obj2)) // "{"a":"replace"}"
ToNumber:数字转换函数详解
ToNumber
ToNumber 机制负责将非数字值强制转换为数字类型。Number()、parseInt() 和 parseFloat() 均可用于执行此类转换。
Number()
Number() 函数的转换规则如下:
- 若输入为 Boolean 类型,true 转换为 0,false 转换为 1。
- 若输入为数字值,则直接原样传入并返回。
- 若输入为 null 值,返回 0。
- 若输入为 undefined,返回 NaN。
- 如果是字符串,遵循下列规则:
- 若字符串仅包含数字,则将其转换为十进制数。
- 若字符串包含有效的浮点格式,则将其转换为对应的浮点数值。
- 若字符串包含有效的十六进制格式,则将其转换为相同大小的十进制数。
- 若字符串为空,则将其转换为 0。
- 若字符串包含除上述格式之外的内容,则将其转换为 NaN。
- 若输入为对象,则先调用对象的 valueOf() 方法,并依据前述规则转换返回值。若转换结果为 NaN,则再调用对象的 toString() 方法,并依据前述规则转换返回的字符串值。
例如:
console.log(Number(true)) // 1
console.log(Number(1)) // 1
console.log(Number(null)) // 0
console.log(Number(undefined)) // NaN
console.log(Number('11')) // 11
console.log(Number('1.1')) // 1.1
console.log(Number('0xf')) // 15
console.log(Number('')) // 0
var a = {
valueOf: function () {
return '10'
}
}
var b = {
toString: function () {
return '10'
}
}
var c = [1, 0]
c.toString = function () {
return c.join("")
}
console.log(Number(a)) // 10
console.log(Number(b)) // 10
console.log(Number(c)) // 10
parseInt()
parseInt() 的转换规则如下:
- parseInt() 函数在转换字符串时,会忽略字符串前面的空格,直到找到第一个非空格字符。
- 如果第一个字符不是数字字符或者负号,parseInt() 将返回 NaN。
- 如果第一个字符是数字字符,parseInt() 会继续解析,直到解析完所有后续字符或者遇到一个非数字字符为止。
- 如果字符串中的第一个字符是数字字符,parseInt() 也能识别各种进制数。
例子:
console.log(parseInt('a')) // NaN
console.log(parseInt('11')) // 11
console.log(parseInt('11aa')) // 11
console.log(parseInt('0xf')) // 15
parseFloat()
parseFloat() 的转换规则如下:
- 与 parseInt() 类似,parseFloat() 从第一个字符开始解析每一个字符,一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。
- 解析时会忽略前导的 0。
- 只会解析十进制数。
例子:
console.log(parseFloat('12.3a')) // 12.3
console.log(parseFloat('0xf')) // 0
console.log(parseFloat('01.1')) // 1.1
ToBoolean:布尔强制转换与假值列表
ToBoolean
布尔强制类型转换的假值(falsy)列表如下:
- undefined
- null
- false
- +0、-0 和 NaN
- ""
除了上述列表以外的值在转换时均为真值(truthy)。强制布尔类型转换常用 Boolean() 或者 !!。第一个 ! 将值强制转为布尔类型,但同时将真假值反转;第二个 ! 将结果再次反转,从而返回原值的布尔状态,例子:
console.log(Boolean("0")) // true
console.log(Boolean([])) // true
console.log(Boolean(undefined)) // false
console.log(!!"0") // true
console.log(!![]) // true
console.log(!!undefined) // false
总结
本文对 JavaScript 中常见的显式强制类型转换进行了小结,希望能帮助大家更好地理解相关机制。
好了,以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对本站的支持。