一、js数据类型:
js数据类型分为六大类,原始数据类型(基本数据类型)和引用数据类型
⑴ js基本数据类型 (五种):
①number ②string ③null ④undefined ⑤boolean
⑵js引用数据类型:
对象Object: function, Array Date等等
解释:
1. 原始数据类型是按照值进行访问的, 存储在栈区里, 赋值是以拷贝赋值
2. 引用数据的值是保存在堆区里,其实操作的是引用数据的地址,地址是保存在栈空间里,赋值其实拷贝赋值其地址
举例:
//1, 基本数据类型:var a = 10;b = a;a = 20;console.log(b);//输出结果为10, 因为基本数据类型进行赋值是拷贝赋值,a的值赋给b,是将a的值拷贝一份给b//2, 引用数据类型:var a = { name: "张三"}var b = a;a.name = "李四";console.log(b.name);//输出结果为 李四 ,因为引用数据类型赋值是进行地址拷贝赋值, a的地址赋给b, b也指向a的地址,两者现在指向的是同一个地址, a的属性name值改变后,b也会随之而改变var a = [1,2,3];var b = a;a = [4,5,6];console.log(b); // [1,2,3]console.log(a); // [4,5,6]//分析: a是一个数组,所以是引用数据类型,栈区存储的是其地址,堆区里存储的是值,当b=a的时候,是将a的地址复制给了b,所以此时b与a指向同一地址,当a重新赋值为[4,5,6]时,a此时在堆空间里指向发生改变了,指向的是[4,5,6]了,而b依然是[1,2,3]复制代码
二、数据类型的判断:
判断一个变量的数据类型,主要有三大方法:typeof, instanceof, Object.prototype.toString()
⑴typeof方法一般是用来判断一个值是数据哪种基本数据类型
typeof "你好"; // stringtypeof true; // booleantypeof 10; // numbertypeof undefined; // undefined// 以下三种其实都属于引用数据类型,对象的子类,但是typeof不能准确的判断其具体的类型typeof null // object 是对象,但是不能具体是哪一个typeof Function //function 函数,此时typeof可以判断其具体类型typeof [] // object,数组判断的是对象typeof {} // object, 对象判断的是对象复制代码
由上可见, typeof并不能准确的判断数据类型
⑵instanceof方法可以对对象类型进行判断 [] instanceof Array; //true{} instanceof Object //trueconsole.log((()=>{}) instanceof Function); //true 注: ()=>{} 是es6中的语法,相当于function(){}函数复制代码
由此可见, instanceof返回值是boolean值, 可以判断其具体类型是否属于后者,但是也不是万能的
比如:
let arr = [];let obj = {};arr instanceof Array; // truearr instanceof Object // trueobj instanceof Object // true复制代码
由上可见, instanceof也不能准确的判断对象类型, arr数组因为也是对象的子类型,其原型也是指向对象的,所以判断其数组为true 对象也为true
在这个例子中,arr 数组相当于 new Array() 出的一个实例,所以 arr.__proto__ === Array.prototype,又因为 Array 属于 Object 子类型,即 Array.prototype.__proto__ === Object.prototype,所以 Object 构造函数在 arr 的原型链上。所以 instanceof 仍然无法判断优雅的判断一个值到底属于数组还是普通对象。
⑶Object.prototype.toString() 方法能判断数据的具体类型
console.log(Object.prototype.toString.call([])); // [object Array]console.log(Object.prototype.toString.call({})); // [object Object]console.log(Object.prototype.toString.call(()=>{})); // [object Function]console.log(Object.prototype.toString.call("")); // [object String]console.log(Object.prototype.toString.call(123)); // [object Number]console.log(Object.prototype.toString.call(true)); // [object Boolean]console.log(Object.prototype.toString.call(null)); // [object Null]console.log(Object.prototype.toString.call(undefined)); // [object Undefined]复制代码
我们可以发现该方法在传入任何类型的值都能返回对应准确的对象类型。用法虽简单明了,但其中有几个点需要理解清楚:
- 该方法本质就是依托Object.prototype.toString() 方法得到对象内部属性 [[Class]]
- 传入原始类型却能够判定出结果是因为对值进行了包装
- null 和 undefined 能够输出结果是内部实现有做处理.