javascript基本数据类型有:string,number,Boolean,undefined,null
引用类型(复杂类型):object,
ES6中新增了一种数据类型:Symbol
以上数据类型中除了object外,所有类型都是不可变的(值本身无法被改变)
1.typeof 用于判断一个表达式,返回值是一个字符串,用法截图看下图
从上面栗子中可以看到type of 检测数组[],{},null,Date(),RegExp()这些都是返回object,所以判断这些类型的时候不能使用typeOf
2.instanceof 用来判断 A 是否为B的实例,返回值是Boolean值,用法截图看下图
从上面栗子中可以看到: [],Array,Object 三者之间的关系:
[].proto指向Array.prototype,而Array.prototype.proto又指向了Object.prototype,最终Object.prototype.proto指向了null,标志着原型链的结束,因此[],Array,Object在内部形成了一条原型链,所以[],Array,Object,instanceOf Object 的结果都是true
eS5中新增了Array.isArray()方法,用于确定某个值是不是数组,用法截图如下:
3.constructor 是当一个函数被定义时,Js会为期添加prototype原型,然后再在prototype上添加一个constructor属性,并让其指向该函数的引用,看下图截图:
当执行 var a = new f()是,f 被当成了构造函数,a 是 f 的实例对象,此时 f 原型上的constructor传递到了a上,因此a.constructor == f
f 利用原型对象上的 constructor 引用了自身,当 f 作为构造函数来创建对象时,原型上的 constructor 就被遗传到了新创建的对象上, 从原型链角度讲,构造函数 f 就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型, javascript中的内置对象在内部构建时也是这样的:
需要注意的是:null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
注意:函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的constructor 引用会丢失,constructor 会默认为 Object
为什么变成了 Object?
因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。
4.toString 是 Object 原型对象上的方法,使用 call 来调用该方法会返回调用者的类型字符串,格式为 [object,xxx],xxx 是调用者的数据类型,包括:String、Number、Boolean、Undefined、Null、Function、Date、Array、RegExp、Error、HTMLDocument 等, 基本上,所有的数据类型都可以通过这个方法获取到。
注意:必须通过 call 或 apply 来调用,而不能直接调用 toString , 从原型链的角度讲,所有对象的原型链最终都指向了 Object, 按照JS变量查找规则,其他对象应该也可以直接访问到 Object 的 toString方法,而事实上,大部分的对象都实现了自身的 toString 方法,这样就可能会导致 Object 的 toString 被终止查找,因此要用 call/apply 来强制调用Object 的 toString 方法。