目录:
- 序
- 正题
- Object.prototype.toString方法探究
- Array.prototype.toString方法探究
- Function......
- String、Boolean和Number
- null和undefined
- window......
- 总结
序:
相信大家面试中经常会出现周末一道题,如何判断数组和对象?
常用的方法有:
1)Array.isArray
2)Object.prototype.toString.call([])
3)[] instanceof Array
4)[].constructor
5)[].__proto__
其中有一种方法为Object.prototype.toString(),
我就好奇为什么非得用Object的toString方法,不是有7种基本数据类型吗,用他们不行吗?他们究竟有什么恩怨情仇?
正题:
我们先明确一下ECMAScript的数据类型,7种
- Undefined
- Null
- String
- Number
- Boolean
- Object
- Symbol(ES6引入)
另外,基于Object类型,JS还实现了其他常用的对象子类型(就是不同类型的对象)
- Object
- Array
- Function
- String
- Boolean
- Number
- Date
- RegExp
- Error
- ...
1、Object.prototype.toString
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]"-->
上述代码可以看到,因为Object是所有子类的父类,所以任何类型的对象object都可以通过this绑定调用Object.prototype.toString()方法,返回该对象的字符串表示!
2、Array.prototype.toString
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);
- 返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串
- 另外null和undefined不可以通过绑定调用Array.prototype.toString()方法。
3、Function.prototype.toString
toString()
方法返回一个表示当前函数源代码的字符串。
Function.prototype.toString.call(function(){}); //"function(){}"
Function.prototype.toString.call({});//Uncaught TypeError: Function.prototype.toString requires that 'this' be a Function
Function.prototype.toString.call([]);//Uncaught TypeError: Function.prototype.toString requires that 'this' be a Function
重写toString()方法,除了function基本不支持
4、基本包装类型(Boolean/Number/String类)
Boolean.prototype.toString.call(true)//"true"
Boolean.prototype.toString.call([])
Boolean.prototype.toString.call({})
Boolean.prototype.toString.call('123')
//Uncaught TypeError: Boolean.prototype.toString requires that 'this' be a Boolean
Number.prototype.toString.call(123)//"123"
Number.prototype.toString.call([])
Number.prototype.toString.call({})
Number.prototype.toString.call('123')
//Uncaught TypeError: Boolean.prototype.toString requires that 'this' be a Boolean
String.prototype.toString.call('666')//"666"
String.prototype.toString.call([])
String.prototype.toString.call({})
String.prototype.toString.call(123)
//Uncaught TypeError: Boolean.prototype.toString requires that 'this' be a Boolean
Boolean/Number/String都重写toString()方法,除了支持自身实例,其他基本不支持。
5、null和undefined
null和undefined没有相应的构造函数,所以它们没有也无法调用toString()方法,也就是说它们不能访问任何属性和方法,只是基本类型而已。
6、window和直接调用
//window调用
window.toString();
<!--"[object Window]"-->
Object.prototype.toString.call(window);
<!--"[object Window]"-->
//直接调用
toString();
<!--"[object Undefined]"-->
Object.prototype.toString.call(undefined);
<!--"[object Undefined]"-->
经查看,Winodw类并没有在Window.prototype原型对象上重写toString()方法,它会顺着原型链查找调用Object.prototype.toString()。
![afec001bd30ba71ac494e86c10af8f1a.png](https://i-blog.csdnimg.cn/blog_migrate/e4716c46d5c4853360a9b5c9456a7595.jpeg)
总结:
- Object.prototype.toString方法,可以说是最原始的toString()方法
- Array.prototype.toString: 返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串;另外null和undefined不可以通过绑定调用Array.prototype.toString()方法。
- 其他类型都基本只支持自身实例,其他基本不支持。
- window和直接调用实质是Object.prototype.toString.call(window)、Object.prototype.toString.call(undefined)
参考:
由Object.prototype.toString.call( )引发关于toString( )方法的思考juejin.im