神奇的传送门
书籍
1. 简介、基本语法基本没啥问题,和以前的认知相同
2. 强制转换 知识
主要指使用Number、String和Boolean三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。
2.1 Number()函数
例如
//数值还是数值
Number(42)//42
//字符串 能全转 才能全转
Number('42') //42
//空字符串转为0
Number(' ')//0
// 布尔值:true 转成1,false 转成0
Number(' true')//1
Number(' false')//0
// undefined:转成 NaN
Number(undefined) // NaN
// null:转成0
Number(null) // 0
Number()很严格,比parseInt()严格。
parseInt('42 cats') // 42
Number('42 cats') // NaN 只要有一个不能转的字符就是NaN
Number函数会自动过滤一个字符串前导和后缀的空格。
Number('\t\v\r12.34\n') // 12.34
分割线强力来袭 ~~~~~~~~~~~~~~~
- 强调一下对象的转换规则
简单的规则是 ***简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。
举例:
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
接下来了解一下Number()
背后的原理。哇擦嘞,以前真是不注意这些东西,菜鸡一枚啊。
1、调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步
骤。
2、如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。
3、如果toString方法返回的是对象,就报错。
原理不好理解,上栗子
var obj = {x: 1};
Number(obj) // NaN
// 等同于
if (typeof obj.valueOf() === 'object') {
Number(obj.toString());
} else {
Number(obj.valueOf());
}
上面的代码意思是:Number函数接收到了obj,先调用obj.valueOf()方法,判断是不是
object
,结果返回对象自身,于是,继续调用obj.toString方法,这时返回字符串[object Object],对这个字符串使用Number函数,必然得到NaN
默认情况下,对象的valueOf()方法总是会返回对象自身,所以一般会调用对象的toString()方法,如果toString()方法,返回对象的类型字符串(比如[object Object]),那么Number(),结果就是NaN;
Number({}) // NaN
如果toString()方法返回不是原始类型的值,就报错(这句话的另一层意思也就是toString()方法被重写了啊)
依然上栗子
obj对象重写了两个方法,注意 toString()方法返回的又是一个对象
报的错 TypeError: Cannot convert object to primitive value
var obj = {
valueOf: function () {
return {};
},
toString: function () {
return {};
}
};
Number(obj)
// TypeError: Cannot convert object to primitive value
2.2 String()函数
使用String函数,可以将任意类型的值转化成字符串。转换规则如下。
- 原始数据类型转换
数值:转为相应的字符串。
字符串:转换后还是原来的值。
布尔值:true转为"true",false转为"false"。
undefined:转为"undefined"。
null:转为"null"。
String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"
- 对象的转换
String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。
- 对象的转换
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
背后的原理基本与Number()相同,只是方法的调用相反
1、先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
2、 如果toString方法返回的是对象,再调用原对象的valueOf方法。如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
3、如果valueOf方法返回的是对象,就报错。
String({a: 1})
// "[object Object]"
// 等同于
String({a: 1}.toString())
// "[object Object]"
上面代码先调用对象的toString方法,发现返回的是字符串[object Object],就不再调用valueOf方法了。
如果toString法和valueOf方法,返回的都是对象,就会报错。
var obj = {
valueOf: function () {
console.log('valueOf');
return {};
},
toString: function () {
console.log('toString');
return {};
}
};
String(obj)
// TypeError: Cannot convert object to primitive value
2.3 Boolean()
除了以下六个值的转换结果为false,其他的值全部为true。
undefined
null
-0
0或+0
NaN
' '(空字符串)
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
- 注意一下
注意,所有对象(包括空对象)的转换结果都是true,甚至连false对应的布尔对象new Boolean(false)也是true。
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true