Open
Description
变量的存放
- 基本类型:保存在栈内存中,因为这些类型在内存中分别占有固定大小的空间,通过按值来访问。基本类型一共有6种:Undefined、Null、Boolean、Number 、String和Symbol
- 引用类型:保存在堆内存中,因为这种值的大小不固定,因此不能把它们保存到栈内存中(影响查询效率),但内存地址大小的固定的,因此保存在堆内存中,在栈内存中存放的只是该对象的访问地址。当查询引用类型的变量时, 先从栈中读取内存地址, 然后再通过地址找到堆中的值。对于这种,我们把它叫做按引用访问。
在计算机的数据结构中,栈比堆的运算速度快,Object是一个复杂的结构且可以扩展:数组可扩充,对象可添加属性,都可以增删改查。将他们放在堆中是为了不影响栈的效率。而是通过引用的方式查找到堆中的实际对象再进行操作。所以查找引用类型值的时候先去栈查找再去堆查找。
复制变量值
- 基本类型:在栈中新开一个字段,将值复制到新字段,新值和旧值是两个独立的字段,互不影响
- 引用类型:在栈中新开一个字段,将对象在堆内存中的地址(引用)复制到新字段,新值和旧值指向堆内存中的同一个对象。
当我们要复制对象时候,操作的是对象的引用。当给对象添加属性的时候,操作的是堆内存中实际的对象。
参数传递
- 按值传递:传递的是实际参数的一个副本,这个值可能是基本类型,也可能是引用类型的地址.
- 引用传递:传递的是实际参数的地址的一个副本
函数参数的传递实际上就是变量的复制。JS中所有的函数参数都是按值传递。引用类型的传递也只不过是按值传递,传递的是"引用地址"指针的值(栈内存中指针的地址)。
例:
function changeStuff(a, b, c) {
a = a * 10; // 对 a 赋值,修改 a 的指向,新的值是 a * 10
b.item = "changed"; // 因为 b 与 obj1 指向同一个对象,所以这里会修改原始对象 obj1.item 的内容
c = {item: "changed"}; // 对 c 重新赋值,修改 c 的指向,其指向的对象内容是 {item: "changed"}
}
变量初始化
var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
调用函数
changeStuff(num, obj1, obj2);
执行函数体
a = a * 10;
b.item = "changed";
c = {item: "changed"};
例2:
function setName(obj){
obj.name = 'zhangsan';
obj = new Object(); // 重写obj时,obj的变量引用就是一个局部对象了,函数执行完后就销毁了
obj.name = 'lisi';
}
var person = new Object();
setName(person);
person.name; // zhangsan
Metadata
Metadata
Assignees
Labels
No labels