1. 原始值(基本数据类型)和引用值(引用类型)
- ECMAScript变量可以包含两种不同类型的数据:原始值和引用值。
- 保存原始值的变量是按值访问
- 引用值就是保存在内存中的对象,js不允许直接访问内存位置,因此也就不能直接操作对象所在的内存空间。在操作对象时,实际操作的是对该对象的引用而非实际的对象本身。为此,保存引用值的变量是按引用访问。
1.1 复制值
除了存储方式不同,原始值和引用值在通过变量复制时也有所不同。
- 原始值:
let data = "1";
let copyData = data;
这里copyData也为1,但是跟存储在data变量中的1是完全独立的。data和copyData是两个可以独立使用,互不干扰的变量,存储在栈中。
- 引用值:
let obj = new Object()
let copyObj = obj;
obj.name = "tom";
console.log(copyObj) //"tom"
这里把引用值从一个变量赋值给另一个变量时,存储在变量中的值也会被复制到新变量所在的位置。区别在于,这里复制的值实际是一个指针,它指向存储在堆内存中的对象,两个变量实际指向同一个对象,因此一个对象上面的变化在另一个对象中反映出来。
1.2 确认类型
- typeof操作符最适合用来判断变量是否为原始值,更确切的说,它是判断一个变量是否为字符串、数值、布尔值或者undefined的最好方式。如果值是null或者对象,那么typeof返回object,typeof虽然对原始值有用,但它对引用值用处不大,我们通常关心一个值是不是对象,而是想知道他是什么类型的对象
- 为了解决这个问题,ECMAScript提供了instanceof操作符。如果变量是给定引用类型的实例,则instanceof操作符返回true。构造函数通过
new可以实例对象,instanceof能判断这个对象是否是之前那个构造函数生成的对象,来看看下面的例子:
let obj = new Object()
console.log(obj instanceof Object) //true
let arr = new Array()
console.log(arr instanceof Array) //true
let str = new String()
console.log(typeof str) //Object
console.log(str instanceof String)//true