1.1 原始值转换为原始值
1.1.1 原始值转为 - Number类型
原始类型值: number string boolean undefined null symbol
Number(123);
Number('123');
Number(' 123');
Number('.123');
Number('1 2');
Number('abc');
Number('');
Number(' ');
Number('true');
Number(true);
Number(false);
Number(undefined);
Number(null);
Number(Infinity);
Number(-Infinity);
Number(-0);
Number(Symbol());
1.1.2 原始值转为 - Boolean类型
虚值(falsey): undefined null 0 NaN '' false;(Boolean类型转换,除了虚值返回的都是true)
Boolean(123); // true
Boolean(Infinity); // true
Boolean('asc'); // true
Boolean(''); // false
Boolean(' '); // true 空格也是字符串
Boolean(true); // true
Boolean(false); // false
Boolean(undefined); // false
Boolean(null); // false
Boolean(NaN); // false
1.1.3 原始值转为 - String类型
原始值被String(参数)转换相当于: 参数 + '' 的形式,直接转为原始值。
String(null); // 'null'
String(123); // '123'
String(true); // 'true'
String(NaN); // 'NaN'
String(false); // 'false'
1.2 对象转为原始值
1.2.1 typeof判断数据类型
typeof数据类型: number string boolean undefined object function symbol
typeof(Infinity); // number
typeof(''); // string
typeof('undefined'); // string 注意,此处加了引号,所以是字符串,而不是undefined
typeof(true); // boolean
typeof(false); // boolean
typeof(undefined); // undefined
typeof(null); // object 这是历史遗留bug,ECMA已经收到多次修正提案,均被拒绝
typeof(function(){}); // function
typeof(Symbol()); // symbol
1.2.2 对象转为 - Boolean类型
只有虚值的情况,Boolean()类型转换的才是false,所以对象转为原始值也是这个规则。
Boolean({}); // true
Boolean(/\d/); // true 正则对象,表示一个空格
Boolean(new Error()); // true
Boolean(Symbol()); // true
1.2.3 对象转为 - Number类型
1. 首先清楚Object.prototype.toString.call()可能出现的结果
// 三大包装类。因为call改变this指向,this指向对象,原始值不是对象,所以系统自动将原始值包装成对象。
console.log(Object.prototype.toString.call(123)); // [object Number]
console.log(Object.prototype.toString.call('abc')); // [object String]
console.log(Object.prototype.toString.call(true)); // [object Boolean]
// toString() 调用 null 返回[object Null],undefined 返回 [object Undefined]。
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(function(){})); // [object Function]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call({})); // [object Object]
// 数字,布尔值不能直接像下面这种方式调用。
console.log(123.toString()); // Uncaught SyntaxError: Invalid or unexpected token
console.log((123).toString()); // 123
// null 和 undefined 两种具体的原始值没有包装类。
console.log(null.toString()); // Uncaught TypeError: Cannot read properties of null (reading 'toString')
console.log(undefined.toString()); // Uncaught TypeError: Cannot read properties of undefined (reading 'toString')
// ECMA262系统内置构造函数
console.log(Object.prototype.toString.call(new Error)); // [object Error]
console.log(Object.prototype.toString.call(/\d/)); // [object RegExp]
console.log(Object.prototype.toString.call(Date)); // [object Function]
console.log(Object.prototype.toString.call(new Date())); // [object Date]
console.log(Object.prototype.toString.call(Symbol())); // [object Symbol]
// 浏览器提供的构造函数。
(function(){
console.log(Object.prototype.toString.call(arguments)); // [object Arguments]
})
(Object.prototype.toString.call(document)); // [object HTMLDocument]
2. 其次清楚valueOf()方法
Object.prototype.valueOf():返回指定对象的原始值。
JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。
因此,不同类型对象的valueOf()方法的返回值和返回值类型均可能不同。
没有看懂没有关系,下面通过4的案例可以明白是怎么回事。
3. 对象转为Number的步骤
var obj = {
toString() {
return 10;
},
valueOf() {
return 20;
}
}
console.log(Number(obj));
1. 明确Number()类型是将对象转换成Number类型,所以先去找valueOf()方法,如果返回值是原始值,就直接通过Number(原始值)进行包装以后返回。
2. valueOf()返回引用值,就去找"自身(valueOf()返回值引用数据类型)"的数据类型的toString()方法,如果没有对象中没有重写toString()方法就通过原型链去父类寻找toString()方法。
3. 如果toString()方法返回原始值,就通过Number(原始值)进行包装以后返回,如果toString()方法返回引用值,就会报错。
5. 案例
console.log(Number([1, 2]));
valueOf --> [1, 2] --> Array.prototype.toString.call([1, 2]) --> '1, 2' --> Number('1, 2');
console.log(Number([10]));
valueOf --> [10] --> Array.prototype.toString.call([10]) --> '10' --> Number('10');
console.log(Number({}));
valueOf --> {} --> Object.prototype.toString.call({}) --> '[object Object]' --> Number('[object Object]');
1.2.4 对象转为 - String类型
var obj = {
toString() {
return 1;
},
valueOf() {
return 2;
}
}
console.log(String(obj));
1. String()转换的本意是转化成字符串,所以首先去寻找toString()方法(没有就去参数数据类型的prototype找),如果toString()返回值是原始值,通过String(原始值)进行包装返回。
2. 如果toString()返回的是引用数据类型,就去寻找valueOf()方法,如果valueOf()方法返回值的是原始值就通过String(原始值)包装返回。
3. 如果valueOf()方法返回的是引用类型数据的值,那么报错。
1.3 隐式类型转换的场景
1.3.1 隐式类型转换涉及布尔转换
if()语句
switch()语句
for(;;)循环
while()循环
! !! && || 逻辑运算
?:三元运算
1.3.2
+(加法运算,拼接字符串) - * / % ++a a-- +a -a
== != >= <= > <
console.log(undefined == null);
console.log(NaN == NaN);
console.log(1 == true);
console.log('1' == true);
console.log('1' == 1);
console.log([] == ![]);
console.log({} == !{});
console.log([1] == 1);
console.log([1] == true);
console.log([] == false);