1.原始值转化原始值
Number既是构造函数,new Number,也是函数
console.log({}==!{});//falseconsole.log([]==![]);//trueconsole.log(Number(undefined)) ;//NaNconsole.log(Number(null));//0
console.log(Boolean(undefined));//falseconsole.log(Boolean(null));//falseconsole.log(Boolean(''))//falseconsole.log(Boolean(' '));//trueconsole.log(Boolean(''))//falseconsole.log(Boolean(' '));//true
console.log(Boolean([]));//trueconsole.log(Boolean({}));//trueconsole.log(Boolean(/d/));//trueconsole.log(Boolean(new Error()));//trueconsole.log(Boolean(Symbol()));//trueconsole.log(typeof Symbol);//function
console.log(Number(Infinity));//Infinityconsole.log(Boolean(Infinity));//true
typeof类型返回值,string、number、boolean、undefined、object、Symbol
console.log(typeof Symbol());//symbolconsole.log(typeof function() {})//functionconsole.log(typeof Date());//stringconsole.log(typeof new Date());//object
console.log(Date())//Mon Feb 14 2022 20:42:32 GMT+0800 (中国标准时间)console.log(new Date())//Mon Feb 14 2022 20:42:32 GMT+0800 (中国标准时间)console.log(Date()==new Date())//trueconsole.log(Date()===new Date)//false

falsey虚值:bool值转换为false的值
‘ ‘里面有东西

Infinity
console.log(typeof Date());//stringconsole.log(typeof new Date());//objectconsole.log(Date())//Mon Feb 14 2022 20:42:32 GMT+0800 (中国标准时间) 函数执行,返回字符串console.log(new Date())//Mon Feb 14 2022 20:42:32 GMT+0800 (中国标准时间) 结果一样 对象,浏览器解析成字符串
对象转Number
var obj={toString() {return 1;},valueOf(){return 2;}}console.log(Number(obj));//2 返回2,是valueOf输出的
var obj={toString() {return 1;},valueOf(){// return 2;return {};}}console.log(Number(obj));//1
对象不能被Number转化,上面的1,是toString方法的,obj上有toString方法时,执行自己的,没有时执行Object上的toString方法
var obj={// toString() {// return 1;// },valueOf(){return {};// return 2;}}console.log(Number(obj))//NaN
var obj={toString1() {return 1;},valueOf(){// return 2;return {};}}console.log(Number(obj));//NaN
Object.prototype.toString.call
传入的原始值都会通过相应的包装类进行包装,比如’123’就是[object String],new String(‘123’);
但Undefined、null是没有对应的包装类的
原始值
console.log(Object.prototype.toString.call('123'));//[object String]console.log(Object.prototype.toString.call(123));//[object Number]console.log(Object.prototype.toString.call(true));//[object Boolean]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([1,2,3]));//[object Array]console.log(Object.prototype.toString.call({}))//[object Object]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]})();console.log(Object.prototype.toString.call(document));//[object HTMLDocument]//不是ecma提供的,有些是不是原生提供的,es6提供的,是windows提供的


console.log(null.toString());console.log(undefined.toString())
都会报错,这样肯定不对
console.log((123).toString());//123// console.log(123.toString())//错误 见如下console.log(null.toString());console.log(undefined.toString())

<div id="test"></div><script>console.log(Object.prototype.toString.call(document))//[object HTMLDocument]</script>
NaN探究
var obj = {toString() {return 1;},valueOf() {return 2;//return '2'; 返回值也是2// return false;//0}}console.log(Number(obj))//2 如果valueof返回的是原始值,返回的2是原始值,不走toString返回方法,Number(2)//valueof返回原始值,把返回的值x进行Number(x),不走tostring方法
var obj = {toString() {return 1;///return false; //0},valueOf() {return {};// return 2;}}console.log(Number(obj))//1 valueof返回引用值,走toString方法,把toString方法的引用值进行Number操作
var obj={/*现在obj没有toString方法了,调用Object原型上的toString方法,Object.prototype.toString.call()方法,返回字符串[object Object],Number()再处理,相当于Number('[object Object]'),这个结果是NaN*/// toString() {// return 1;// },valueOf(){return {};// return 2;}}Number('sdfa');//NaNNumber('123');//console.log(Number(obj))//NaN
var obj = {toString() {return {};},valueOf() {return {};}}console.log(Number(obj))//NaNconsole.log( Number())//;console.log(obj.toString())
如果经过toString方法不能变成原始值,就会报错
上面的是[object Object]字符串,是原始值
总结
1 valueof返回的是原始值x,直接Number(x),不走toString方法
2 如果是引用值:对象,走toString方法,走Object原型的toString


console.log([1,2,3].toString());console.log(Array.prototype.toString.call([1,2,3]))console.log({}.toString());//对象没有包装类,调用object原型上的方法console.log(Object.prototype.toString.call({}))console.log(false.toString())// Boolean.prototype.toString(); 调用的是Boolean原型上的方法,false先new Boolean(false)变成包装类,有object原型的tostring方法,又有boolean原型上的tostring方法,所以调用boolean上的toString方法console.log(Boolean.prototype.toString.call(false))console.log(Object.prototype.toString.call(false))
不同的对象调用toString,调用的toString方法不同,false是原始值没有toString方法·,但包装类new Boolean(false).toString(),如下
console.log(new Boolean(false).toString())//false

Object.prototype.toString.call(obj);var obj={toString(){return {};},valueOf(){return {};}}console.log([1,2,3].valueOf());console.log({}.valueOf());// Boolean.prototype.toString();console.log((false).valueOf());// console.log(Number('[object Object]'));console.log(Number(obj))

var obj={toString(){return {};}}console.log(obj.valueOf())console.log(obj)//一样

[1,2,3];[10];console.log([]);console.log(Array.prototype.toString.call([1,2,3]));console.log(Array.prototype.toString.call([10]));console.log(Object.prototype.toString([]));console.log(Object.prototype.toString.call([]))// [].toString// new Array();// Array.prototype.toStringconsole.log(Boolean.prototype.toString.call(false));// Array.prototype.slice.call(arguments);// [].slice.call(arguments);console.log([].toString()==Array.prototype.toString);console.log([].toString==Array.prototype.toString);// console.log([].toString.call()==Array.prototype.toString.call());console.log(Number([1,2]));//因为是数组,valueof返回的是[1,2]是引用值,所以走,因为Array.prototype.toString返回1,2的字符串,再进行Number操作,结果是NaNconsole.log(Number([10]));//因为Array.prototype.toString返回10的字符串,再进行Number操作,结果是10console.log(Number({}));//NaNconsole.log(Array.prototype.toString.call(false));console.log(Array.prototype.toString.call(123));console.log(Array.prototype.toString.call('123'));console.log(Array.prototype.toString.call({}));console.log(Boolean.prototype.toString.call(false));console.log(Boolean.prototype.toString.call('false'));//报错 必须是false或者trueconsole.log(Boolean.prototype.toString.call(123));//报错 是什么就返回什么,调用什么console.log(Boolean.prototype.toString.call('123'));console.log(Boolean .prototype.toString.call({}));console.log(Number.prototype.toString.call(false));console.log(Number.prototype.toString.call(123));console.log(Number.prototype.toString.call('123'));console.log(Number.prototype.toString.call({}))
总结二
console.log(Number([1,2]));//NaN/*因为是数组,valueof返回的是[1,2]是引用值,因为Array.prototype.toString返回1,2的字符串,再进行Number操作,结果是NaN*/console.log(Number([10]));//10//因为Array.prototype.toString返回10的字符串,再进行Number操作,结果是10console.log(Number({}));//NaN//相当于console.log(Number((1).valueOf()));console.log(Number(Array.prototype.toString.call([1,2])));console.log(Number(Array.prototype.toString.call([10])))console.log(Number(Object.prototype.toString.call({})))console.log(typeof [])//objectconsole.log(Object.prototype.toString.call([]))//[object Array] 根据Object原型的toString区分格式
console.log(Number(1))//1console.log(Number((1).valueOf()));//1console.log(Number(new Number(1).valueOf()));//1console.log(Number(Number.prototype.valueOf.call(1)))//1//这几个是一个意思,转换时不同的数据,调用不同对象原型的valueof、toString方法




