对象
对象就是一组属性的集合,属性包括属性名和属性值。属性名也叫键名,属性值也叫键值,所以对象的属性也叫键值对
const superman = {
name: 'superman',
age: 21,
eat: function () {
console.log('I eat something');
},
};
- 对象为引用类型
const superman = {};
typeof superman; // 'object'
Object.prototype.toString.call(superman); // '[object Object]'
创建对象
构造函数创建对象
JS 提供了一个内置的构造函数 Object
来创建对象
const obj = new Object(); // 创建空对象
obj.name = 'superman'; // 添加属性
console.log(obj); // { name: 'superman' }
字面量创建对象
const obj = {
name: 'superman',
age: 18,
};
console.log(obj); // { name: 'superman', age: 18 }
使用字面量创建对象时,属性名默认都为 String 类型。一般情况下,可以不加引号。
但是,如果属性名不符合标识符规范,则需要加引号将其包裹!
不符合标识符规范:
① 有 字母
、数字
、下划线 _
、美元符 $
以外的字符
② 以 数字
开头(不加也好使,但不推荐)
③ 属性名中有 空格
④ 属性名是 关键字
、保留字
(不加也好使,但不推荐)
const obj = {
'**': '哈哈',
};
console.log(obj); // { '**': '哈哈' }
操作对象的属性
对象的属性值,可以是任意类型(eg: String、Number、Boolean、RegExp、Object、Array、Function…)
const obj = {
name: 'superman', // 字符串
age: 21, // 数字
isStudent: true, // 布尔值
hair: undefined, // undefined
class: null, // null
children: ['superSon', 'superDaughter'], // 数组
wife: { name: 'superwoman' }, // 对象
eat: function () {},
};
// 遍历对象的类型及其属性值
for (const item of Object.values(obj)) {
console.log(Object.prototype.toString.call(item) + ' ' + item);
}
[object String] superman
[object Number] 21
[object Boolean] true
[object Undefined] undefined
[object Null] null
[object Array] superSon,superDaughter
[object Object] [object Object] ———— 注意看这里,Object 转 String 会变成 `[object Object]`
[object Function] function () {}
添加 & 更新属性
const obj = {};
console.log(obj); // {}
obj.name = 'superman'; // 无则添加
console.log(obj); // { name: 'superman' }
obj.name = 'monster'; // 有则覆盖
console.log(obj); // { name: 'monster' }
删除属性
可以通过 delete
关键字删除对象属性
const obj = {
name: 'superman',
};
console.log(obj); // { name: 'superman' }
delete obj.name; // 删除属性
console.log(obj); // {}
查询属性
- 可以通过
.
/[]
来获取对象的属性值 []
内的属性名要用""
括起来(就是说[]
里面的是字符串)
const obj = {
name: 'superman',
age: 21,
};
console.log(obj); // { name: 'superman', age: 21 }
console.log(obj.name); // superman
console.log(obj['name']); // superman
console.log(obj.age); // 21
console.log(obj['age']); // 21
- 对于不符合标识符规范的属性名,只能通过
[]
获取属性值 - 因为
[]
里面的是字符串,所以可以进行字符串拼接等操作 []
里面的属性名,可以用对应的字符串变量代替
.
后面必须是对象的属性名,不可以是变量
const obj = {
'**': '*****',
};
console.log(obj); // { '**': '*****' }
console.log(obj['**']); // *****
console.log(obj['*' + '*']); // *****
let a = '**';
console.log(obj1[a]); // *****
-
属性名为数字(不推荐) / 数字字符串时,
[]
内可以不用引号;但不能用.
有点像数组,但其实数组就是特殊的对象(以下标为属性名,元素为属性值,且有 length 属性的对象)
const obj = {
1: 'superman',
2: 18,
};
console.log(obj[1]); // superman
console.log(obj['1']); // superman
console.log(obj[2]); // 18
console.log(obj['2']); // 18
对象的特点
对象转为 String 类型都等于
'[object Object]'
const a = {};
console.log(a + ''); // [object Object]
属性名都为 String 类型的
如果属性名不是 String 类型,会被隐式转成 String 类型
const obj = {}; // 创建对象 obj
// 创建对象 a
const a = {
key: 'a',
};
// 创建对象 b
const b = {
key: 'b',
};
obj[a] = 123; // 对象 a 被隐式转换为 String
obj[b] = 345; // 对象 b 被隐式转换为 String
console.log(obj); // { '[object Object]': 345 }
// 对象被转为 String 后,都为 [object Object]
console.log(obj[a]); // 345
console.log(obj[b]); // 345
console.log(obj['[object Object]']); // 345
// 对象 a b 还可以正常使用
console.log(a); // { key: 'a' }
console.log(b); // { key: 'b' }
this
的使用
在对象的方法内,可以使用 this
来指代当前对象:
const obj = {
age: 18,
growUp: function () {
this.age++; // 相当于 obj.age++
},
};
console.log(obj.age); // 18
obj.growUp(); // 调用方法
console.log(obj.age); // 19
需要注意的是,如果对象的方法为箭头函数,则没有 this
可用:
const obj = {
age: 18,
growUp: () => {
this.age++; // 使用箭头函数, 这里的 this 指向 window
},
};
console.log(obj.age); // 18
obj.growUp(); // 调用方法
console.log(obj.age); // 18 —— obj.age 没有被成功修改
操作对象
遍历对象
- 可以使用
for … in
遍历对象
const obj = {
name: 'superman',
age: 18,
};
// 使用 for … in 遍历对象
for (const key in obj) {
// 变量 key → 对象的属性名
console.log(key, obj[key]); // name superman age 18
}
-
还可以使用
for … of
遍历对象注意:
for … of
不能直接遍历对象,因为for … of
只能操作可迭代对象
for (const key of Object.keys(obj)) {
console.log(key, obj[key]); // name superman age 18
}
克隆对象
- 对象的复制不能直接使用
=
赋值,因为操作符会直接操作引用类型数据的存储地址 - 可以使用
structuredClone
进行深拷贝(注意:structuredClone
无法拷贝函数)
const obj = { name: '张三', age: { real: 21, fake: 18 } };
const cloneObj = structuredClone(obj);
cloneObj.age.real = 40;
console.log('cloneObj', cloneObj); // { name: '张三', age: { real: 40, fake: 18 } }
console.log('obj', obj); // { name: '张三', age: { real: 21, fake: 18 } }
structuredClone
同样适用于数组的深拷贝:
const arr = [1, 2, 3, 4, 5];
const cloneArr = structuredClone(arr);
cloneArr[0] = 10;
console.log('cloneArr', cloneArr); // [10, 2, 3, 4, 5]
console.log('arr', arr); // [1, 2, 3, 4, 5]