toString来源
Object类型的每个实例都有toString()方法,返回对象的字符串表示
'[object,Object]',所以每个实例化对象都可以调用toString方法.
顺着实例化对象原型链obj=>obj._proto_=>Object.prototype知道
toString方法是定义在Object.prototype上的
- 然而不同类型都或多或少的重写了toString()方法 ,因此不同类型调用toString()方法会产生的值各不相同
不同对象toString方法的返回
对象Object
对象类型的调用toString方法都会返回
对象的字符串表示
- 下面是一种常见的判断类型的方法 任何对象都可以通过this绑定调用Object.prototype.toString()方法 返回对象的字符串表示
Object.prototype.toString.call({});
<!--"[object Object]"-->
Object.prototype.toString.call([]);
<!--"[object Array]"-->
Object.prototype.toString.call(function(){});
<!--"[object Function]"-->
Object.prototype.toString.call('');
<!--"[object String]"-->
Object.prototype.toString.call(1);
<!--"[object Number]"-->
Object.prototype.toString.call(true);
<!--"[object Boolean]"-->
Object.prototype.toString.call(null);
<!--"[object Null]"-->
Object.prototype.toString.call(undefined);
<!--"[object Undefined]"-->
Object.prototype.toString.call();
<!--"[object Undefined]"-->
Object.prototype.toString.call(new Date());
<!--"[object Date]"-->
Object.prototype.toString.call(/at/);
<!--"[object RegExp]"-->
数组Array
返回由数组中每个值的
字符串形式拼接而成的以逗号分隔的一个字符串
var array = [1, 's', true, {a: 2}];
array.toString();//"1,s,true,[object Object]"
Array.prototype.toString.call(array);//"1,s,true,[object Object]"
- 以上可以看出 数组对象可以通过this绑定调用Array.prototype.toString()方法,返回数组值的字符串拼接
Array.prototype.toString.call({});
<!--"[object Object]"-->
Array.prototype.toString.call(function(){})
<!--"[object Function]"-->
Array.prototype.toString.call(1)
<!--"[object Number]"-->
Array.prototype.toString.call('')
<!--"[object String]"-->
Array.prototype.toString.call(true)
<!--"[object Boolean]"-->
Array.prototype.toString.call(/s/)
<!--"[object RegExp]"-->
Array.prototype.toString.call();
<!--Cannot convert undefined or null to object at toString-->
Array.prototype.toString.call(undefined);
Array.prototype.toString.call(null);
- 但是非数组对象通过this绑定调用Array.prototype.toString方法,返回的是该对象的字符串表示。
- 另外null和undefined不可以通过绑定调用Array.prototype.toString方法
函数Function
toString():返回函数的代码
function foo(){
console.log('function');
};
foo.toString();
<!--"function foo(){-->
<!-- console.log('function');-->
<!--}"-->
Function.prototype.toString.call(foo);
<!--"function foo(){-->
<!-- console.log('function');-->
<!--}"-->
注意
Object.toString();
//"function Object() { [native code] }"
Function.toString();
//"function Function() { [native code] }"
Array.toString();
//"function Array() { [native code] }"
....
- 以上构造函数的toString方法都是返回的函数代码
Function.prototype.toString.call({});
<!--Function.prototype.toString requires that 'this' be a Function-->
非函数对象不能通过绑定this来调用原型方法
日期Date
返回带有时区信息的日期和时间
var date = new Date();
date.toString();
//"Fri Mar 05 2020 16:53:43 GMT+0800 (中国标准时间)"
Date.prototype.toString.call(date);
//"Fri Mar 05 2020 16:53:43 GMT+0800 (中国标准时间)"
正则表达式RegExp
返回正则表达式的字面量
var reg = /cat/g;
reg.toString();// "/cat/g"
RegExp.prototype.toString.call(re);// "/cat/g"
基本包装类型
什么是基本包装类型((Boolean、Number、String))
var str = 'beatrix';
str.toString();//"beatrix"
str不是一个基本类型吗,怎么可以调用toString方法呢?
- str 和strObject 的区别
var str = 'I am a string';
typeof str; //"string"
str instanceof String; //false
var strObject = new String('I am a string');
typeof strObject; //"object"
strObject instanceof String; //true
strObject instanceof Object; //true
- 由于String基本包装类型的存在,在必要的时候JS引擎会把字符串字面量转换成一个String对象
过程:
创建一个String类型的实例--->在这个实例上调用指定的方法--->销毁这个实例
var strObject = new String('beatrix');
strObject.toString(); //'beatrix'
strObject = null;
字符串 String
返回字符串的一个副本
var str = "a";
str.toString(); //"a"
String.prototype.toString.call(str); //"a"
数值Number
返回字符串形式的数值
var num = 520;
num.toString(); //"520"
Number.prototype.toString.call(num); //"520"
布尔值Boolean
返回字符串形式的数值
var boo = true;
boo.toString(); //"true"
Boolean.prototype.toString.call(boo); //"true"
undefined和null
null和undefined没有相应的构造函数,所以它们没有也无法调用toString()方法,也就是说它们不能访问任何属性和方法,只是基本类型而已。
全局对象window
Object、Array、Function都是window对象的属性。
返回对象的字符串表示
window.toString();
<!--"[object Window]"-->
Window.prototype.toString.call(window);//这里其实有问题
<!--"[object Window]"-->
- Winodw类并没有在Window.prototype原型对象上重写toString()方法,它会顺着原型链查找调用Object.prototype.toString()。
- 所以,任何对象object都可以通过this绑定调用Window.prototype.toString()方法,也就是调用Object.prototype.toString()方法,结果和Object是一样。
直接调用toString
toString();
<!--"[object Undefined]"-->
(function(){
console.log(toString());
})();
<!--[object Undefined]-->
直接调用等价于
Object.prototype.toString.call();
<!--"[object Undefined]"-->
Object.prototype.toString.call(undefined);
<!--"[object Undefined]"-->
直接调用toString.call
toString.call({});
<!--"[object Object]"-->
toString.call([]);
<!--"[object Array]"-->
等价于Object.prototype.toString() 但是如果重写了toString方法就不会默认调用原型对象上的toString方法
总结
除了Object和Array两种情况,其他类型都不支持非自身实例通过this绑定调用该Object子类原型对象上的toString()方法,这说明在重写toString()方法时,明确限定了调用该方法的对象类型。
所以,一般我们只使用Object.prototype.toString.call/apply()方法来通过this绑定调用,判断其准确类型。