JavaScript 支持的数据类型可分为两大类:基本数据类型和复杂数据类型。其中基本数据类型包含了数字(number)类型、字符串(string)类型、布尔(boolean)类型、未定义(undefined)类型、空(null)类型;复杂数据类型包含了对象(object)类型,在 JavaScript 中数组、函数都属于对象类型。除了基本数据类型以外的数据类型全都是对象类型。
在 JavaScript 中,基本数据类型变量分配在栈内存中,其中存放了变量的值,对其是按值来访问的;而对象类型的变量则同时会分配栈内存和堆内存,其中栈内存存放的是地址。堆内存存放的是引用类型的值,栈内存存放的地址指向堆内存中存放的值。对该变量的访问是按引用来访问的,即首先读取到栈内存存放的地址,然后按该地址找到堆内存读取其中存放的值。
JavaScript 之所以按变量的不同数据类型来分配内存,主要原因是栈内存比堆内存小,而且栈内存的大小是固定的,而堆内存大小可以动态变化。基本数据类型的值的大小固定,对象类型的值大小不固定,所以将它们分别存放在栈内存和堆内存是合理的。
接下来以下面的代码为例,以图示的方法介绍其中不同类型变量的内存分配情况。
function Student(id,sno,name,age){ //函数定义,Student是一个函数变量 this.id = id; this.sno = sno; this.name = name; this.age = age; } var num = 20; //num是一个数字变量 var bol = false; //bol是一个布尔变量 var str = "student"; //str是一个字符串变量 var obj ={}; //obj是一个对象变量 var arr = ['a','b','c']; //arr是一个数组变量 var student = new Student(1,"2017010200016","小华",18);//student是一个对象变量
上述代码中的 Student 变量定义了一个构造函数(有关构造函数以及后面的使用构造函数和使用{}创建对象的内容之后介绍),函数的定义代码存放在堆内存中,该内存对应的地址存放在 Student 函数变量中。构造函数用于创建对象实例,最后一行代码正是使用了该构造函数来创建了一个名字为小华的学生对象实例。学生实例创建完后会返回其在堆内存中分配的地址,该地址被赋给了 student 变量。
上述代码中的{}
在堆内存中创建了一个空对象,该对象的堆内存中的地址被赋给了 obj 变量。['a','b','c'] 是一个元素值分别为 'a'、'b'、'c' 的数组对象,该对象也在堆内存中存放,其对应的地址赋给了 arr 变量。除了 Student、obj、arr 和 student 这几个变量为对象变量外,其他几个变量 num、bol、str 都是基本数据类型的变量,因而它们都存储在栈内存中。
上述代码中各个类型变量的内存分配情况如图 1 所示。
图 1:不同类型变量的内存分配情况
图 1 清楚地描述了基本数据类型的变量值存储在栈内存,而对象类型变量,包括函数、数组和对象,在栈内存中存储的只是引用对象的地址,该地址为对象在堆内存中分配的地址,因而通过该地址可以找到对象类型变量值。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/21407.html