js 中对象可以转化成 字符串, 数字, 布尔值
一, 对象转化成字符串:
规则:
1, 如果对象有 toString 方法, 则调用该方法, 并返回相应的结果;(代码通常会执行到这, 因为在所有对象中都有 toString 方法)
2, 如果对象有 valueOf 方法, 则调用该方法, 并返回相应的结果;
3, 否则抛出异常.
通常, 所有对象都有 toString 方法, 且内置对象都有自己 toString 方法的实现
- alert( {key: 'value'} ) // [object Object]
- alert( [1,2] ) // "1,2"
- alert( new Date() ) // "Sat Sep 15 2018 15:58:01 GMT+0800 (中国标准时间)"
在界面输出中, 比如 alert() 和 document.write() , 将优先调用 toString, 如果过得不到 标量 或 undefined,null , 再尝试 valueOf , 如果仍然返回对象则报错.
其实 parseInt(), alert(), document.write() 这些函数的调用中, 参数所进行的类型转换, 应当视为 "被动的" , 是函数的实现方式使之优先调用 toString, 而非数据对象自动调用 toString.
可以自定义 toString()
- var obj = {
- age:23,
- toString:function(){
- return this.age;
- }
- }
- obj.toString();//23
二, 对象转化成数字
需要转化成数字的两种主要情况:
函数里边的参数需要是数字, 如: Math.sin(obj) / isNaN(obj) 以及算术运算符: +obj ;
用于比较, 如: obj == 'John'
PS: 下面两种比较不会发生类型转换,
a)在严格比较 (===) 中, 不会发生任何的类型转换,
b)在非严格比较中, 如果参数都是对象, 不会发生类型转换, 通常, 如果两个对象引用统一对象, 则返回 true.
转化成数字的规则:
1, 如果对象有 valueOf 方法, 则调用该方法, 并返回相应的结果;
2, 当调用 valueOf 返回的依然不是数字, 则会调用对象的 toString 方法, 并返回相应的结果;
3, 否则抛出异常.
对象的 valueOf 方法返回的是对象本身, 而不是字符串(比如数组, 函数, 它们的 valueOf 方法是从 Object.prototype 上继承下来的, 默认行为是返回对象本身), 所以才会采用 toString
对于对象型参与 算术运算和 "==" 运算, 不等于比较元算(> ,<,>=,<=), 自动发生数据类型转换, 先调用 valueOf , 如果 valueOf 不能返回标量(number,string,boolean) 和 undefined, null ,
将继续调用 toString, 如果仍然返回对象型数据, 报错.
Date 类型的例外: 在 + 和 == 运算中, 优先 toString , 这应该是规范对该数据类型的特殊对待.
补充: 调用 valueOf()的结果:
参数类型 | 返回结果 |
Undefined | 抛出 TypeError 异常 |
Null | 抛出 TypeError 异常 |
Number | 创建一个 Number 对象, 它内部的初始值为传入的参数值 |
String | 创建一个 String 对象, 它内部的初始值为传入的参数值 |
Boolean | 创建一个 Boolean 对象, 它内部的初始值为传入的参数值 |
Object | 对象本身 |
可以重写对象的 valueOf()方法(百度一道面试题, 定义一个对象, 使 obj == '1' , 结果为 true):
- var obj = {
- valueOf: function(){
- return 1;
- }
- };
- console.log(obj == '1');//true
三, 对象转化成布尔值:
对象在 JS 中总是返回 true
根据上述, 对象在相等性判断中如何转变?
在布尔上下文中, a 是 true , b 是 false,a == b, 这是可能的 .
[] == ![] //true
内部的转化步骤:
1, 右边是![], 将会被转换成一个布尔值,[]为 true, 取非为 false, 此时表达式变成:
[]==false;
2, 按照规则, 右边是布尔值, 将 false 转换成 0, 左边是数组, 数组也将进行数字转换, 先调用 valueOf(), 不能转化成原始值, 再用 toString(), 转换为 0
0 == 0
3, 结果为 true
补充 == 和!= 判断规则(注意:===!== 和 对象 == 对象 这三种情况不会进行类型转换):
如果有一个操作数是布尔值, 则在比较相等性之前先将其转换为数值 ----false 转化为 0,true 转化为 1;
如果有一个数是字符串, 另一个操作数是数值, 将字符串转化成数值;
如果一个操作数是对象, 另一个操作数不是对象, 将对象转化为基本操作类型 (先 valueOf() 再 toString(), 均不能得到基本类型的值则会报错), 再比较.
所以, 对象在相等性判断中:
若两边都是对象, 不会进行类型转换, 为同一个引用才会返回 true
若只有一边为对象, 则会先调用对象的 valueOf()方法, 不能返回基本类型, 再调用对象的 toString()方法, 还是不能就会报错, 否则用转化后的基本类型值继续进行判断
举例, 感受下~:
- []==[]//false
- []==false//true
- !![]//true
- []==![]//true
总结:
在 JavaScript 中, 对象有三个转换, 这取决于具体情况:
字符串输出, 使用 toString .
数字: 数学函数, 操作符, 使用 valueOf 后使用 toString .
布尔值: 转化为 true.
来源: https://www.cnblogs.com/lihuijuan/p/9643570.html