栈:基本类型:Undefined、Null、Boolean、Number、String
堆:引用类型:Array、Object、Function
Symbol和BigInt是ES6新增的数据类型:
Symbol:创建独一无二且不可变的数据类型,主要是为了解决可能出现的全局变量冲突的问题。
BigInt:是一种数字类型的数据,可以表示任意精度格式的整数。用于安全的存储和操作大数据。
两种类型的区别在于存储位置不同:
1、原始数据类型存放在栈中,占据空间小、大小固定,被频繁使用。
2、引用类型存储在堆中的对象,占据空间大、大小不固定,在栈中存储了指针,该指针指向堆中该实体的起始地址。
1、typeof:object、null、array类型的值都是object,其他类型的都是正确。
console.log(typeof 2); // number console.log(typeof true); // boolean console.log(typeof 'str'); // string console.log(typeof []); // object console.log(typeof function(){}); // function console.log(typeof {}); // object console.log(typeof undefined); // undefined console.log(typeof null); // object
2、instanceof:其内部运行机制是判断在其原型链中能否找到该类型的原型。(不能检测基本类型,只能检测引用类型)
//基本类型无法检测 console.log(2 instanceof Number); // false console.log(true instanceof Boolean); // false console.log('str' instanceof String); // false //引用类型可以检测 console.log([] instanceof Array); // true console.log(function(){} instanceof Function); // true console.log({} instanceof Object); // true
3、constructor
console.log((2).constructor === Number); // true console.log((true).constructor === Boolean); // true console.log(('str').constructor === String); // true console.log(([]).constructor === Array); // true console.log((function() {}).constructor === Function); // true console.log(({}).constructor === Object); // true
4、Object.prototype.toString.call()
var a = Object.prototype.toString; console.log(a.call(2));//[object Number] console.log(a.call(true));//[object Boolean] console.log(a.call('str'));//[object String] console.log(a.call([]));//[object Array] console.log(a.call(function () { }));//[object Function] console.log(a.call({}));//[object Object] console.log(a.call(undefined));//[object Undefined] console.log(a.call(null));//[object Null]
1、通过Object.prototype.toString.call()做判断
var arr = []; console.log(Object.prototype.toString.call(arr).slice(8,-1) === 'Array');//true
2、通过原型链做判断
var arr = [112, 2] console.log(arr.__proto__ === Array.prototype);//true
3、通过ES6的Array.isArray()做判断
var arr = [112, 2] console.log(Array.isArray(arr));//true
4、通过instanceof做判断
var arr = [112, 2] console.log(arr instanceof Array);//true
5、通过Array.prototype.isPrototypeOf
var arr = [112, 2] console.log(Array.prototype.isPrototypeOf(arr));//true
同:都是基本数据类型,都存放在栈中。
异:
1、含义:null是空对象,主要用于初始化;undefined是未定义,定义未赋值的变量,值为undefined。
2、保留字:null是保留字不可以作为变量名;undefined不是保留字,可以用作变量名,输出不会报错,但是会产生冲突。
3、typeof:typeof null === ‘object’;typeof undefined === ‘undefined’。
console.log(null == undefined);//true console.log(null === undefined);//false
console.log(0.1 + 0.2 === 0.3) // false 为什么呢?
因为计算机是通过二进制的方式存储数据的,所以计算0.1+0.2的时候,需要先转化为二进制再求和,这其中存在着一些精度误差,0.1+0.2=0.30000000000000004。
可以通过四舍五入进行判断
console.log((0.1+0.2).toFixed(2)==0.3);//true
NaN 指“不是一个数字”(not a number),NaN 是一个“警戒值”(sentinel value,有特殊用途的常规值),用于指出数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。
console.log(typeof NaN); // "number" console.log(NaN !== NaN)
1、函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。
console.log(isNaN(1));//false console.log(isNaN('1'));//false console.log(isNaN('a'));//true console.log(isNaN('a'/2));//true
2、函数 Number.isNaN 会首先判断传入参数是否为数字
,如果是数字
再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。
console.log(Number.isNaN(1));//false console.log(Number.isNaN('1'));//false console.log(Number.isNaN('a'));//false console.log(Number.isNaN('a' / 2));//true
对于 == 来说,如果对比双方的类型不一样,就会进行类型转换。假如对比 x 和 y 是否相同,就会进行如下判断流程:
1、首先会判断两者类型
是否相同,相同的话就比较两者的大小;
2、类型不相同的话,就会进行类型转换;
3、会先判断是否在对比 null 和 undefined,是的话就会返回 true;
4、判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。