本质:二元操作符 + 规则
如果操作数是对象,则对象会转换为原始值
如果其中一个操作数是字符串的话,另一个操作数也会转换成字符串,进行字符串连接
否则,两个操作数都将转换成数字或NaN,进行加法操作
对象转为原始数据类型的值的方法
Symbol.ToPrimitive
Symbol.toPrimitive
是 JavaScript 内置对象 Symbol
中的一个 Symbol 值,它用于指定一个对象在进行类型转换时的转换行为。
当我们将一个对象转换为基本类型值时,JavaScript 引擎会调用对象的 valueOf()
和 toString()
方法来尝试获取其原始值。但是有时候我们需要对这种类型转换的行为进行控制,这时候可以在对象上实现 Symbol.toPrimitive
方法。
具体来说,如果一个对象定义了 Symbol.toPrimitive
方法,那么在进行类型转换时,JavaScript 引擎会优先调用该方法来获取对象的原始值,而不是调用 valueOf()
和 toString()
方法。
Symbol.toPrimitive
方法接受一个参数 hint
,用于指定转换的目标类型,它可以是以下三个值之一:
"number"
:表示需要将对象转换为数字类型。"string"
:表示需要将对象转换为字符串类型。"default"
:表示需要根据上下文来确定转换目标类型。
Symbol.toPrimitive
方法应该返回一个原始值,它表示对象所代表的原始值。如果 Symbol.toPrimitive
方法未被实现,或者返回的值不是原始值类型,则会抛出 TypeError 异常。
需要注意的是,Symbol.toPrimitive
方法是一个符号属性,需要使用 Symbol.toPrimitive
调用该方法。例如,myObj[Symbol.toPrimitive](hint)
。
Object.prototype.valueOf
Object.prototype.valueOf()
是 JavaScript 内置对象 Object
的原型方法之一。它的作用是返回当前对象的原始值,这个值可以是任何 JavaScript 基本类型(例如字符串、数字、布尔值等)或者是 null
或 undefined
。
当我们在某个对象上调用 valueOf()
方法时,JavaScript 引擎会尝试将该对象转换成原始值。如果对象本身已经是原始值类型,那么 valueOf()
方法直接返回该值。否则,它会尝试调用对象的 toString()
方法将其转换成字符串,然后再返回该字符串对应的原始值。
需要注意的是,Object.prototype.valueOf()
方法是一个默认实现,通常情况下应该由派生自 Object
的子类来覆盖该方法以实现更具体的行为。
Object.prototype.toString
Object.prototype.toString()
是 JavaScript 内置对象 Object
的原型方法之一。它的作用是返回一个表示当前对象的字符串。
当我们在某个对象上调用 toString()
方法时,JavaScript 引擎会根据对象的类型不同,返回不同的字符串。具体来说:
- 对于基本类型值,如字符串、数字、布尔值等,会返回对应的字符串形式。
- 对于对象类型值,会返回一个形如
"[object Object]"
的字符串,其中 "Object" 表示对象的类型名,可以通过Object.prototype.toString.call()
来获取。例如,Object.prototype.toString.call([])
返回的字符串为"[object Array]"
,表示该对象是一个数组类型。
需要注意的是,Object.prototype.toString()
方法是一个默认实现,通常情况下应该由派生自 Object
的子类来覆盖该方法以实现更具体的行为。
二元操作符 toNumber
[] + [], [] + {}, {} + [], {} + {}
如何求原始值
[]的原始值
- typeof [][Symbol.ToPrimitive] // undefined
- [].valueOf() // []
- [].toString() // ''
{}的原始值
- typeof {}[Symbol.ToPrimitive] // undefined
- {}.valueOf() or ({}).valueOf() // {}
- ({}).toString() // '[object Object]'
[] + []
- [].toString() + [].toString()
- '' + ''
- ''
[] + {}
- [].toString() + ({}).toString()
- '' + '[object Object]'
- '[object Object]'
{} + []
- {}; + [].toString()
-
- ''
- 0
{} + {}
其他浏览器控制台:
- {}; + {}
-
- '[object Object]'
- NaN
chrome浏览器控制台:
- ({}+{})
- '[object Object]'+'[object Object]'
- '[object Object][object Object]'