判断数据类型的方式:
1. Object.prototype.toString
对象原型上的toString方法,在对象的this属性上有可以判断数据类型的隐藏属性[[class]],其他的数据类型都有自己的toString方法,但是他们的toString方法被重写了跟Object.prototype.toString不一样。
比如:
(1)定义一个变量a是一个数字:var a = 1;
(2)a的类型:typeof a == "number";
(3)a调用toString方法:a.toString() == "1";
(4)为什么a是一个数字也可以调用toString方法呢?因为:a.constructor == ƒ Number() { [native code] }; a 是由构造函数Number()new出来的;既然是构造函数构造出来,其实也可以看做是一个特殊的对象
(5)a的原型上是有toString方法,不过这个方法是重写的,跟Object.prototype.toString的方法不一样了。同样的,数组、对象、布尔值等都重写了toString方法
原型上包含了所有的方法,可以通过__proto__来查看这些方法,从而使用这些方法。
数组原型上也是:
注意:length: 0是原型的length属性的值,arr有自己的length属性,有自己的值。
(6)分别来看一下,不同类型的数据调用toString方法后的结果:
对象:
数组:
布尔值:
(7)除了对象调用toString方法得到的值判断数据类型,其他的都是转换为字符串,当然,每个类型的toString实现的方式也是不同,比如:数组就是每一项都会调用toString方法,而得到的字符串。
(8)根据上面的变量a,可以调用toString方法,因为构造函数内的this对象有一个 [[Class]] 隐藏的属性(internal property),该属性的值就是类型:
内部属性 | 描述 |
[[Class]] | 一个字符串值,表明了该对象的类型. |
只有最原始的对象的原型上的toString方法具有[[Class]]属性,而该属性正是来区分数据类型的,其他toString方法都被重写了,失去了判断类型的功能;正因为如此,我们通过call来改变this指向,进而使得Object.prototype.toString.call()可以避开自己的toString方法,而去调用原型上的toString方法,才能确定数据类型。
(9)在toString方法被调用时,会执行下面的操作步骤:
获取this对象的[[Class]]属性的值.
计算出三个字符串"[object ", [[Class]]属性的值, 以及 "]"连接后的新字符串.
返回计算的的结果
(10)在ES3中,规范文档并没有总结出[[class]]内部属性一共有几种,不过我们可以自己统计一下,原生对象的[[class]]内部属性的值一共有10种.分别是:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object", "RegExp", "String".
(11)ECMAScript 5,对象的[[Class]]属性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.
ES5的Object.prototype.toString ( )
在toString方法被调用时,会执行下面的操作步骤:
如果this的值为undefined,则返回"[object Undefined]".
如果this的值为null,则返回"[object Null]".
让O成为调用ToObject(this)的结果.
让class成为O的内部属性[[Class]]的值.
返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.
(12)Arguments类型
function func(a,b,c){
console.log(arguments);
console.log(Object.prototype.toString.call(arguments));
}
func(1,2,3);
结果:Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
[object Arguments]
2. 如果能明白toString方法的原理,还可以这么写:
var obj = {};
obj.toString.call([])
//结果
"[object Array]"
参考: