一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
一、认识对象
对象(Object)是“键值对”集合,表示属性和值的映射关系。
var obj = {
name: 'zhangsan',
age: 18,
sex: '男',
'favorite-fruit': '西瓜'
}
- 以{}包括,每组k:v之间用逗号分隔,最后一组k:v可以不加逗号
- 若属性名不符合JS命名规范,那么需要用引号包裹,如'favorite-fruit'
二、属性相关操作
2-1、属性的访问
可以使用“点语法”来访问属性:
obj.name
obj.age
obj.sex
若属性名不符合JS命名规范,那么必须使用方括号写法来访问:
obj['favorite-fruit']
若属性名以变量的方式进行存储,也要通过方括号写法进行访问:
var obj = {
a: 1,
b: 2,
c: 3
}
var key = 'c'
console.log(obj[key])
2-2、属性的修改
直接使用赋值运算符直接对某属性进行赋值即可
var obj = {
a: 1,
b: 2,
c: 3
}
obj.a = 5
obj.b ++
2-3、属性的创建
如果对象本身没有该属性,直接通过点语法为该属性赋值即可创建该属性
var obj = {
a: 1,
b: 2,
c: 3
}
obj.d = 8
2-4、属性的删除
如果要删除某个属性,需要使用delete操作符
var obj = {
a: 1,
b: 2,
c: 3
}
delete obj.a
三、对象的方法
如果某个属性值是函数,则它也被成为对象的“方法”:
var obj = {
name: 'zhangsan',
age: 18,
sex: '男',
'favorite-fruit': '西瓜',
sayHello: function() {
console.log('你好')
}
}
- 使用“点语法”可对方法进行调用:
obj.sayHello()
四、对象的遍历
与遍历数组类似,对象也可以被遍历,遍历对象使用for...in...循环
- 使用for...in...循环可遍历出对象的每个键
for(var k in obj) {
console.log('key: ' + k + 'value: ' + obj[k])
}
五、对象的浅克隆与对象深克隆
5-1、基本类型值与引用类型值
举例 | 当var a = b变量传值时 | 当用==比较时 | |
---|---|---|---|
基本类型值 | 数字、字符串、布尔、undefined、null | 内存中产生新的副本 | 比较值是否相等 |
引用类型值 | 对象、数组等 | 内存中不产生新的副本,而是让新变量指向同一个对象 | 比较内存地址是否相同,即比较是否为同一个对象 |
由于对象是引用类型值,这就意味着:
不能够使用var obj2 = obj1这样的语法克隆一个对象,这会使得obj1的地址值赋值给obj2,使得obj2与obj1指向同一片堆内存区域
- 使用==或者===进行对象的比较时,比较的是他们是否为内存中的同一个对象,而不是比较值是否相同
var obj1 = {
a: 1,
b: 2,
c: 3
};
var obj2 = {
a: 1,
b: 2,
c: 3
};
console.log(obj1 == obj2); // false
console.log(obj1 === obj2); // false
console.log({} == {}); // false
console.log({} === {}); // false
var obj3 = {
a: 10
};
var obj4 = obj3; // obj4与obj3指向同一个对象,而不是对obj3进行克隆
obj3.a ++;
console.log(obj4); // {a: 11}
5-2、对象的浅克隆
对象的浅克隆即:只克隆对象的“表层”,如果对象的某些属性值又是引用类型值,则不进行进一步克隆,只是传递它们的引用。
- 使用for...in...可实现对象的浅克隆
var obj1 = {
a: 1,
b: 2,
c: [1,2,3,4,5]
};
// 实现浅克隆
var obj2 = {};
for (var k in obj1) {
obj2[k] = obj1[k];
}
// 为什么叫浅克隆呢?比如c属性的值是引用类型值,那么本质上obj1和obj2的c属性是内存中的同一个数组,并没有被克隆分开。
obj1.c.push(6);
console.log(obj2); // obj2的c中也会多了数字6
console.log(obj1.c == obj2.c); // true,true就证明了数组是同一个对象
5-3、对象的深克隆
对象的深克隆即克隆对象的全貌,无论其属性值是否又为引用类型,都进行克隆。
- 需要使用递归进行克隆
var obj1 = {
a: 1,
b: 2,
c: [11, 22, {
m: 33,
n: 44,
p: [55, 66]
}]
};
// 深克隆
function deepClone(o) {
// 要判断o是对象还是数组
if (Array.isArray(o)) {
// 数组
var result = [];
for (var i = 0; i < o.length; i++) {
result.push(deepClone(o[i]));
}
} else if (typeof o == 'object') {
// 对象
var result = {};
for (var k in o) {
result[k] = deepClone(o[k]);
}
} else {
// 基本类型值
var result = o;
}
return result;
}
var obj2 = deepClone(obj1);
console.log(obj2);
console.log(obj1.c == obj2.c);// false
obj1.c.push(77);
console.log(obj2); // obj2不变,因为实现了深克隆,obj1中的c与obj2中的c是两个完全不同的数组
obj1.c[2].p.push(88);
console.log(obj2);// obj2不变的,实现深克隆后,obj1中c[2]的p数组与obj2中的c[2]的p数组是两个完全不同的数组
要注意,由于typeof 数组的结果也为'object',所以要先通过Array.isArray来判断一下该引用类型值是否为数组,再去判断该引用类型值是否为对象。