JS的数据类型
JS的基本数据类型:Undefined、Null、Boolean、Number、String
- Undefined类型只有一个值,即特殊的undefined,声明变量但是没有初始化,这个变量的值就是undefined
- Null类型只有一个值null,表示一个空对象指针,正式使用typeof操作符检测null会返回object
- Boolean有两个字面值:true和false
- Number:用来表示整数和浮点数,还有一种特殊的值即NaN,这个数值用来表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)
- String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以由单引号(')或双引号(")表示。
引用类型
- Object类型
- Array类型
- Function类型
- Date类型
- RegExp类型
基本包装类型
Boolean、Number、String
基本类型与引用类型的区别
存储空间:基本类型存在栈中,引用类型存在栈上
值传递:基本类型传递的是值,引用类型传递的是地址(引用)
作为函数的参数:基本类型传递的是值,引用类型传递得是地址
判断js数据类型的方法:
1.typeOf
可以对除了null以外的其他基本类型做出判断,对于引用类型,typeof返回的是object
- typeof ""; //"string"
- typeof 1; //"number"
- typeof false; //"boolean"
- typeof undefined; //"undefined"
- typeof function(){}; //"function"
- typeof {}; //"object"
- typeof Symbol(); //"symbol"
- typeof null; //"object"
- typeof []; //"object"
- typeof new Date(); //"object"
- typeof new RegExp(); //"object"
- typeof new Number(33) //"object"
- typeof Null //"undefined"
2.instanceof
instanceof运算符只能用于对象,不适用原始类型的值。
instanceof判断A是否是B的实例,表达式为:A instanceof B(判断A是否是B的实例),如果是返回true,否则返回false。在原型链上的原型都可以返回true的
- [] instanceof Array; // true
- [] instanceof Object; // true
所以instanceof只能判断两个对象是否属于实例关系,不能具体判断一个对象实例属于哪种类型
undefined、null用instanceof 会报错
3.constructor
constructor返回的是对象的构造函数,当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向自身。
- var f=new F()
- f.constructor===F // true
注意:
1.null和undefined是无效的对象,因此不会有constructor存在,这两种类型数据需要通过其他方式判断。
2.函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
- F.prototype={a:"XXXX"}
- var ff=new F()
- ff.constructor===F // false
- ff.constructor // ƒ Object() { [native code] }
*为什么变成了 Object?
因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。
const arr = []; console.log(arr.constructor === Array); // true const obj = {}; console.log(obj.constructor === Object); // true const num = 1; console.log(num.constructor === Number); // true const str = '1'; console.log(str.constructor === String); // true const bool = true; console.log(bool.constructor === Boolean); // true const nul = null; // console.log(nul.constructor); // 报错:Uncaught TypeError: Cannot read property 'constructor' of null at <anonymous>:1:5 const undefin = undefined; // console.log(undefin.constructor); // 报错:Uncaught TypeError: Cannot read property 'constructor' of null at <anonymous>:1:5
因此重写原型一般需要给constructor重新赋值ff.constructor=F
4.Object.prototype.toString.call()
toString()是Object的原型方法,调用该方法,默认返回当前对象的[[Class]]。这是一个内部属性,其格式为[object Xxx],其中Xxx就是对象的类型。
- Object.prototype.toString.call("a")
- "[object String]"
- Object.prototype.toString.call(undefined)
- "[object Undefined]"
- Object.prototype.toString.call(null)
- "[object Null]"
- Object.prototype.toString.call(new Date())
- "[object Date]"
同样是检测对象obj调用toString方法(关于toString()方法的用法的可以参考toString的详解),obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?
这是因为toString为Object的原型方法,而Array 、Function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(Function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。