ES5标准中,js一共有七种数据类型,后来在ES6中,又新增了一个数据类型(Symbol,类似于string的数据类型,表示独一无二的),加起来就是八种:
字符串(string)、数字(number)、布尔(boolean)、Null、Undefined、Symbol、数组(array)、对象(object)
基本类型(值类型):
字符串(string)、数字(number)、布尔(boolean)、Null、Undefined、Symbol
1. 基本类型是不可变的,这里的不可变,是说基本类型指向的内存空间不变,例如:
var a=3;
a=a+2;
console.log(a)
最后的输出结果是5,这里a变量所指向的值确实变了,但是在计算机内存中,进行的操作是在原先的基础上,又重新请求了一个‘2’的内存,然后加起来得到的‘5’,也就是说并没有对原先申请的内存‘3’进行变动,而是拼接。
2. 基本类型的访问是按值访问的,就是说你可以操作保存在变量中的实际的值。
3.基本类型的变量是存放在栈区的(栈区指内存里的栈内存),栈区包括了 变量的标识符和变量的值。:
//js代码
var name = 'jozo';
var city = 'guangzhou';
var age = 22;
那么它的存储结构如下图:
引用类型:
数组(array)、对象(object)
1. 引用类型是可变的,这里的可变,指得是计算机内存是可变的,例如:
var array=[1,2,3,4];
array.push(5)
console.log(array)
结果输出’[1,2,3,4,5]’,在计算机内存中,不会重新生成一个完整的数组,而是接在原先申请的[1,2,3,4]的内存上进行修改。
之所以值类型和引用类型在内存中的操作不同,是因为值类型包含的数据量一般较小,复制的成本比较低,引用类型包含的数据量一般比较大,并且复杂,复制的成本比较高,所以js引擎在实现的时候,就会对二者进行区别对待。
2. 引用类型的访问是按引用访问,当查询时,我们需要先从栈中读取内存地址,然后再顺藤摸瓜地找到保存在堆内存中的值;
var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};
则这三个对象的在内存中保存的情况如下图:
实际上,这些数据类型都可以用”!!”强制转换成对应的boolean类型:
数据类型 | 转换成的boolean值 | 实例 |
---|---|---|
String | 1.字符串不为空(包括空格):true 2.字符串为空:false | 1.!!"abc"==>true !!" "==>true 2. !!""==>false |
Number | true | !!123=>true |
Array | 无论数组是否为空,都为true | 1.!![1,2,3]==>true 2. !![]==>true |
Object | 无论对象是否为空,都为true | 1.!!{"abc":"def"}==>true 2. !!{}==>true |
Null | false | !!null==>false |
Undefined | false | !!undefined==>false |
Symbol | 无论是否为空,都为true | 1.!!Symbol('foo')==>true 2. !!Symbol()==>true 3. !!Symbol('')==>true |