1.原始值转化原始值
Number既是构造函数,new Number,也是函数
console.log({}==!{});//false
console.log([]==![]);//true
console.log(Number(undefined)) ;//NaN
console.log(Number(null));//0
console.log(Boolean(undefined));//false
console.log(Boolean(null));//false
console.log(Boolean(''))//false
console.log(Boolean(' '));//true
console.log(Boolean(''))//false
console.log(Boolean(' '));//true
console.log(Boolean([]));//true
console.log(Boolean({}));//true
console.log(Boolean(/d/));//true
console.log(Boolean(new Error()));//true
console.log(Boolean(Symbol()));//true
console.log(typeof Symbol);//function
console.log(Number(Infinity));//Infinity
console.log(Boolean(Infinity));//true
typeof类型返回值,string、number、boolean、undefined、object、Symbol
console.log(typeof Symbol());//symbol
console.log(typeof function() {})//function
console.log(typeof Date());//string
console.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())//true
console.log(Date()===new Date)//false
falsey虚值:bool值转换为false的值
‘ ‘里面有东西
Infinity
console.log(typeof Date());//string
console.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 (中国标准时间) 结果一样 对象,浏览器解析成字符串
对象转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');//NaN
Number('123');//
console.log(Number(obj))//NaN
var obj = {
toString() {
return {};
},
valueOf() {
return {};
}
}
console.log(Number(obj))//NaN
console.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.toString
console.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操作,结果是NaN
console.log(Number([10]));
//因为Array.prototype.toString返回10的字符串,再进行Number操作,结果是10
console.log(Number({}));//NaN
console.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或者true
console.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操作,结果是10
console.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 [])//object
console.log(Object.prototype.toString.call([]))
//[object Array] 根据Object原型的toString区分格式
console.log(Number(1))//1
console.log(Number((1).valueOf()));//1
console.log(Number(new Number(1).valueOf()));//1
console.log(Number(Number.prototype.valueOf.call(1)))//1
//这几个是一个意思,转换时不同的数据,调用不同对象原型的valueof、toString方法