类型转化
转 Boolean
以下都为假值,其他所有值都转为 true,包括所有对象(空对象,空数组也转为真)。
- false
- undfined
- null
- ''
- NaN
- 0
- -0
对象转基本类型
对象在转换基本类型时,会调用valueOf
, 需要转成字符类型时调用toString
。
var a = {
valueOf() {
return 0
},
toString() {
return '1'
},
}
1 + a // 1
'1'.concat(a) //"11"
也可以重写 Symbol.toPrimitive
,该方法在转基本类型时调用优先级最高。 Symbol.toPrimitive 指将被调用的指定函数值的属性转换为相对应的原始值。
类型转换
运算中其中一方为字符串,那么就会把另一方也转换为字符串 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串
1 + '1' // '11'
true + true // 2
4 + [1, 2, 3] // "41,2,3"
还需要注意这个表达式'a' + + 'b'
'a' + +'b' // -> "aNaN"
因为 + 'b' 等于 NaN,所以结果为 "aNaN",你可能也会在一些代码中看到过 + '1' 的形式来快速获取 number 类型。
{}
等于 true 还是 false
var a = {}
a == true // -> false
a == false // -> false
if (a) {
console.log('进来') // 会输出
}
因为 a.toString() -> '[object Object]' ,而一个
100 +
问题
'100' + 100 // "100100"
100 + '100' // "100100"
100 + true // 101
100 + false // 100
100 + undefined //NaN
100 + null // 100
parseInt
的坑
parseInt(0.0000001) // 1
parseInt('0.0000001') // 0
parseInt(1000000000000000000000) // 1
parseInt('1000000000000000000000') // 1e+21
;(0.0000001).toString() // "1e-7"
1 与 Number(1)有什么区别
var a = Number(1) // 1
var b = new Number(1) // Number {[[PrimitiveValue]]: 1}
typeof a // number
typeof b // object
a == b // true
- var a = 1 是一个常量,而 Number(1)是一个函数
- new Number(1)返回的是一个对象
- a==b 为 true 是因为所以在求值过程中,总是会强制转为原始数据类型而非对象,例如下面的代码:
typeof 123 // "number"
typeof new Number(123) // "object"
new Number(123) instanceof Number // true
123 === new Number(123) // false
console.log(!!(new Boolean(false))输出什么 [易混淆]
true 布尔的包装对象 Boolean 的对象实例,对象只有在 null 与 undefined 时,才会认定为布尔的 false 值,布尔包装对象本身是个对象,对象->布尔 都是 true,所以 new Boolean(false)其实是布尔的 true,看下面这段代码:
if (new Boolean(false)) {
alert('true!!')
}
只有使用了 valueOf 后才是真正的转换布尔值,与上面包装对象与原始资料转换说明的相同:
!!new Boolean(false) //true
new Boolean(false).valueOf() //false
Object.prototype.toString
如果是原始类型,他会将原始类型包装为引用类型,然后调用对应方法
function dd() {}
var toString = Object.prototype.toString
toString.call(dd) //[object Function]
toString.call(new Object()) //[object Object]
toString.call(new Array()) //[object Array]
toString.call(new Date()) //[object Date]
toString.call(new String()) //[object String]
toString.call(Math) //[object Math]
toString.call(undefined) //[object Undefined]
toString.call(null) //[object Null]
toString.call(123) //[object Number]
toString.call('abc') //[object String]
obj.toString() 和 Object.prototype.toString.call(obj)
同样是检测对象 obj 调用 toString 方法,obj.toString()的结果和 Object.prototype.toString.call(obj)的结果不一样,这是为什么?
这是因为 toString 为 Object 的原型方法,而 Array ,function 等类型作为 Object 的实例,都重写了 toString 方法。不同的对象类型调用 toString 方法时,根据原型链的知识,调用的是对应的重写之后的 toString 方法(function 类型返回内容为函数体的字符串,Array 类型返回元素组成的字符串.....),而不会去调用 Object 上原型 toString 方法(返回对象的具体类型),所以采用 obj.toString()不能得到其对象类型,只能将 obj 转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用 Object 上原型 toString 方法。
输出以下代码运行结果
1 + "1"
2 * "2"
[1, 2] + [2, 1]
"a" + + "b"
- 1 + "1"
- 加性操作符:如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
- 所以值为:“11”
- 2 * "2"
- 乘性操作符:如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值
- [1, 2] + [2, 1]
- Javascript 中所有对象基本都是先调用 valueOf 方法,如果不是数值,再调用 toString 方法。
- 所以两个数组对象的 toString 方法相加,值为:"1,22,1"
- "a" + + "b"
- 后边的“+”将作为一元操作符,如果操作数是字符串,将调用 Number 方法将该操作数转为数值,如果操作数无法转为数值,则为 NaN。
- 所以值为:"aNaN"