2-5. 引用类型
原始类型、引用类型(对象、函数)
- 原始类型的变量,存放的具体的值;
- 引用类型的变量,存放的是内存地址(引用);
对象字面量
- 但凡是出现对象字面量的地方,一定在内存中开辟了一段空间,用于存放对象 ;
垃圾回收
- 垃圾回收,若一个对象没有变量指向它,那么它将被视为垃圾,这段内存空间将会被回收;
- 仅创建了一个对象
//obj1 指向 xx 对象
//obj1 持有 xx 对象的引用(地址)
var obj1 = {
name: "123",
age: 10
}; // 出现对象字面量的位置,会新开辟一块内存空间,用于存放对象的内容
/* 说明:
左边 = 右边; // 运算顺序是: 先执行赋值符号右边的表达式,再将得到的结果赋给左边的变量
此时赋值符号右边是 {
name: "123",
age: 10
};
右边的这一部分会在内存中开辟一段内存空间,这段内存空间里面存放的就是 {name:"123",age:10} 这个对象;
且右边的运算结果是在这段内存空间的地址,所以左边的变量将会存放执行这段内存空间的地址;
*/
// obj2 和 obj1 指向同一个对象
// obj2 和 obj1 持有相同的引用(地址)
var obj2 = obj1;
obj2.name = "456";
console.log(obj1.name, obj2.name); // 456 456
- 创建了两个对象
var obj1 = {
name: "123",
age: 10
};
var obj2 = obj1;
obj2 = {
name: "456"
};
console.log(obj1.name, obj2.name); // 123 456
- 创建了3个对象
var user1 = {
name: "u1",
address: {
country: "中国",
city: "哈尔滨"
}
};
var user2 = {
name: "u2",
address: user1.address
};
user2.name = "user2";
user2.address.city = "成都";
console.log(user1.name, user2.name); // u1 user2
console.log(user1.address.city, user2.address.city); // 成都 成都
- 创建了3个对象
var obj1 = {
a: "123",
b: "456",
sub: {
s1: "abc",
s2: "bcd"
}
};
var temp = obj1.sub;
var obj2 = obj1;
obj2.sub = {
s1: "s",
s2: "ddd"
};
console.log(obj1.sub.s1, obj2.sub.s1, temp.s1);// s s abc
- [扩展]JS中的垃圾回收
垃圾回收器,会定期的发现内存中无法访问到的对象,该对象称之为垃圾,垃圾回收器会在合适的时间将其占用的内存释放。
// 补充:在JS中,变量在使用时可以不写 var
// 不写 var 直接赋值,相当于给 window 的某个属性直接赋值。
a = 1;
console.log(a, window.a); // 1 1
- 练习1
//说出以下程序是否有问题,问题在哪?
//中国象棋中有4个马,每个马是一个对象,为了方便对象的创建,写出如下代码
var horse1 = {
name: "马",
position: { //马在棋盘上的位置
x: 1,
y: 9
},
color: "red" //马的颜色
};
var horse2 = horse1;
horse2.position.x = 7;
var horse3 = horse1;
horse3.name = "馬";
horse3.position.y = 0;
horse3.color = "black";
var horse4 = horse3;
horse4.position.x = 7;
// 答: 上述4个horse 操作的实际上都是同一匹马
console.log(horse1.color, horse1 === horse2, horse1 === horse3, horse1 === horse4); // "black" true true true
- 练习2
//以下程序的输出结果是什么
var obj1 = {
a: "a1",
subObj: {
prop: "p1"
}
};
var obj2 = {
a: "a2",
subObj: {
prop: "p2"
}
};
obj2.subObj = obj1.subObj;
obj2.subObj.prop = "p3";
console.log(obj1.subObj.prop, obj2.subObj.prop); // "p3" "p3"
- 练习3
var a = 3,
b = 5;
//将两个变量交换
var temp = a;
a = b;
b = temp;
var a = 3,
b = 5;
//将两个变量交换
a = a + b;
b = a - b;
a = a - b;
var item = {
name: "foo",
parent: {
name: "bar"
},
child: {
name: "goo"
}
};
// 将item的parent和child互换,不可创建新对象
// item.parent item.child
var temp = item.parent;
item.parent = item.child;
item.child = temp;
// item ==> {name: "foo", parent: {…}, child: {…}}
// child: {name: "bar"}
// parent: {name: "goo"}
// 下面这种写法无效 不要拿地址作运算
var item = {
name: "foo",
parent: {
name: "bar"
},
child: {
name: "goo"
}
};
item.parent = item.parent + item.child;
item.child = item.parent - item.child;
item.parent = item.parent - item.child;
// item ==> {name: "foo", parent: NaN, child: NaN}