- 说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费,如需要项目实战或者是体系化资源,文末名片加V!
- 作者:哈哥撩编程,十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。
- 荣誉:2022年度博客之星Top4、2023年度超级个体得主、谷歌与亚马逊开发者大会特约speaker、全栈领域优质创作者。
- 🏆 白宝书系列
- 🏅 启示录 - 攻城狮的自我修养
- 🏅 Python全栈白宝书
- 🏅 ChatGPT实践指南白宝书
- 🏅 产品思维训练白宝书
- 🏅 全域运营实战白宝书
- 🏅 大前端全栈架构白宝书
文章目录
- ⭐ 对象的方法
- ⭐ 对象的遍历
- ⭐ 对象的深浅克隆
- 🌟 对象的浅克隆
- 🌟 对象的深克隆
⭐ 对象的方法
如果
某个属性值是函数
,则它被称为对象的“方法”
示例代码:下面的对象中,byeBye这个属性的值是一个函数,那么这个属性是这个对象的方法
var xiaomumu = {
name: '小沐沐',
age: 2,
sex: '男',
hobbies: ['秋千', '滑梯'],
'favorite-books': ['抱抱', '我的爸爸'],
byeBye: function () {
console.log('挥手再见');
}
};
方法的调用
可以通过打点的方式调用对象的方法
示例代码:
var xiaomumu = {
name: '小沐沐',
age: 2,
sex: '男',
hobbies: ['秋千', '滑梯'],
'favorite-books': ['抱抱', '我的爸爸'],
byeBye: function () {
console.log('挥手再见');
}
};
xiaomumu.byeBye(); // 在控制台输出 挥手再见
学到这里,我们可以总结出方法和函数的区别了:方法也是函数,只不过方法是对象的“函数属性”,它需要打点调用,比如以前我们学过的一些方法有console.log()
、Math.ceil()
等,log就是console对象的方法,ceil是Math对象的方法
⭐ 对象的遍历
和遍历数组一样,我们也可以对对象进行遍历,其实就是使用循环的方式来访问对象中的每个属性
遍历对象需要使用
for...in...
循环,for…in…循环可以遍历对象的每个键
语法如下:
for (var k in obj) { // k是循环变量,它会依次成为对象的每一个键;obj是对象的名字
consloe.log(k);
consloe.log(obj[k]); // obj[k]是k对应的属性值,注意必须使用方括号,不能使用打点
};
下面我们来遍历xiaomumu这个对象,把它的属性名和属性值输出到控制台:
var xiaomumu = {
name: '小沐沐',
age: 2,
sex: '男',
hobbies: ['秋千', '滑梯'],
'favorite-books': ['抱抱', '我的爸爸'],
byeBye: function () {
console.log('挥手再见');
}
};
// 变量xiaomumu对象
for (var k in xiaomumu) {
console.log('属性名' + k + '对应的属性值' + xiaomumu[k]);
}
⭐ 对象的深浅克隆
先来复习一下基本类型值和引用类型值
举例 | 当var a = b变量传值时 | 当用或=比较时 | |
---|---|---|---|
基本类型值 | 数字、字符串、布尔、undefined、null | 内存中产生新的副本 | 比较的是"值"是否相等 |
引用类型值 | 对象、数组等 | 内存中不产生新的副本,而是让新变量指向同一个对象 | 比较的是“内存地址”是否相同,即比较是否为同一个对象 |
因为对象是引用类型值
,所以:
- 对象不能通过var obj2 = obj1的方式来克隆一个对象,这样“克隆”出来的变量会和原变量指向同一个堆内存区域,当改变一个对象的值时,另一个值也会发生改变
- 使用或者=进行比较时,比较的是它们是否为内存中的同一个对象,而不是比较值是否相同
我们实际敲一些代码来证明对象是引用类型值:
var obj1 = {
a: 10
}
var obj2 = obj1;
obj1.a++;
console.log(obj2.a); // 11(改变obj1的值,obj2的值也会改变)
console.log({} == {}); //false (用==比较,答案是false,因为两个空数组指向的内存地址不同)
console.log({ a: 1 } === { a: 1 }); //false (用===比较,答案也是false)
🌟 对象的浅克隆
浅克隆,只克隆对象的“表层”,如果对象的某些属性值又是引用类型值,则不进一步克隆它们,只是传递它们的引用
使用for…in…循环既可以实现对象的浅克隆
示例代码:
var xiaomumu = {
name: '小沐沐',
age: 2,
sex: '男',
hobbies: ['秋千', '滑梯'],
};
var muxiaomu = {};
// 浅克隆,只克隆表层
for (var k in xiaomumu) {
muxiaomu[k] = xiaomumu[k]; // 把xiaomumu的键值赋值给muixiaomu的键值
}
console.log(muxiaomu); // 和原对象看起来完全相同
console.log(muxiaomu == xiaomumu); //false,证明指向的堆内存地址不同了,对象被成s功克隆
console.log(muxiaomu.hobbies == xiaomumu.hobbies); // true,证明这个hobbies属性没有被正在的克隆,所以这种克隆方式是“浅克隆”
🌟 对象的深克隆
深克隆,克隆对象的全部,不论对象的属性值是否又是引用类型值,都能将它们实现克隆
和数组的深克隆类似,对象的深克隆也需要使用
递归
,面试常考
示例代码:
var xiaomumu = {
name: '小沐沐',
age: 2,
sex: '男',
hobbies: [
'秋千',
{
'吃水果': ['蓝莓', '香蕉', '西瓜']
},
'滑梯']
};
// 深克隆
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 muxiaomu = deepClone(xiaomumu); //深克隆一个对象
console.log(muxiaomu);
一定要注意,在使用typeof判断是否是对象时,数组类型也会被判断为object,所以在写判断条件时,一定要注意书写的顺序。