JavaScript数据类型分为两类:
- 基本数据类型:
- Number 数值型
- String 字符串型
- Boolean 布尔型
- Symbol
- BigInt
- Null
- Underfined
- 引用数据类型:
- Object
基本数据类型和引用数据类型区别:
1、ECMAScript变量包含的两种不同数据类型的值:
- 基本类型值, 指的是简单的数据段
- 引用类型值, 指的是那些可能由多个值构成的对象
2、解析过程不同:
将一个值赋给变量时,解析器必须确定这个值是基本类型值(Undefined,Null,Boolean,String,Number,Symbol,BigInt),还是引用类型值。
基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值
引用类型的值是保存在堆内存中的对象,与其他语言不同,JavaScript不允许直接访问堆内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是操作对象的引用地址而不是实际的对象,为此,引用类型的值是按引用地址访问的。
3、基本数据类型与引用数据类型存储方面的区别
- 基本数据类型保存在栈内存中;
- 引用数据类型保存在堆内存中;
在从一个变量复制基本类型值和引用类型值时,也存在着不同:
在复制基本类型值时,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上,如下示例:
var num1 = 5;
var num2 = num1;
在此,num1中保存的值是5.当使用num1的值来初始化num2时,num2中也保存了值5,但两者中的5是完全独立的,num2中的值只是num1中5的一个副本。此后两个变量参与的任何操作都不会相互影响。
当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象
复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另一个变量。
var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Jack";
console.log(obj2.name); // "Jack"
首先,变量obj1保存了一个对象的新实例的引用
然后,这个值被复制到了obj2中,这样两者都指向同一对象
当为obj1天假name属性后,就可以通过obj2来访问这个属性了,因为两者指向同一对象。
基本数据类型与引用数据类型作为参数传递上的区别
ECMAScript中所有函数的参数都是按值传递的
ECMAScript中所有函数的参数都是按值传递,也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。
在向参数传递基本类型值时,被传递的值会被复制给一个局部变量(即命名参数,或者用ECMAScripot的概念来说,就是arguments对象中的一个元素)
在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反应在函数的外部。
function setName(obj){
obj.name = "Jack";
}
var person = new Object();
setName(person);
console.log(person.name); //"Jack"
以上代码创建了一个对象,并将其引用保存在了变量person中,然后这个变量被传递到了setName()函数中之后就被复制给了obj。
在这个函数内部,obj和person引用的是同一个对象,于是在函数内部为obj添加name属性后,函数外部的person也将有所反应,因为person指向的对象在堆内存中只有一个
使用instanceof操作符来检测引用类型值。
使用typeof操作符来检测基本数据类型。