1.3 对象与数组
对象和数组是 JavaScript 中最重要的数据结构,用于存储和组织数据。
一、对象(Object)
1. 创建对象
javascript
// 对象字面量
const person = {
name: "张三",
age: 25,
city: "北京",
greet: function() {
console.log("Hello!");
}
};
// new Object()
const person2 = new Object();
person2.name = "李四";
person2.age = 30;
// 工厂函数
function createPerson(name, age) {
return {
name,
age,
greet() {
console.log(`Hello, I'm ${this.name}`);
}
};
}
const person3 = createPerson("王五", 28);
// 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
console.log(`Hello, I'm ${this.name}`);
};
}
const person4 = new Person("赵六", 27);2. 访问属性
javascript
const person = {
name: "张三",
age: 25,
"full name": "张三丰"
};
// 点表示法
console.log(person.name); // "张三"
// 方括号表示法
console.log(person["age"]); // 25
console.log(person["full name"]);// "张三丰"(必须用于特殊属性名)
// 动态属性名
const key = "name";
console.log(person[key]); // "张三"3. 添加/修改/删除属性
javascript
const person = { name: "张三" };
// 添加属性
person.age = 25;
person.city = "北京";
// 修改属性
person.name = "李四";
// 删除属性
delete person.city;
// Object.defineProperty(定义属性)
const obj = {};
Object.defineProperty(obj, "name", {
value: "张三",
writable: true, // 可写
enumerable: true, // 可遍历
configurable: true, // 可删除
get() {
return "张三";
},
set(value) {
// 设置逻辑
}
});4. 对象方法
javascript
const person = {
name: "张三",
age: 25,
greet() {
console.log(`Hello, I'm ${this.name}`);
},
sayHello: function() {
console.log(`Hello!`);
}
};
person.greet(); // 调用方法
person["greet"](); // 另一种方式5. 遍历对象
javascript
const person = { name: "张三", age: 25, city: "北京" };
// for...in
for (let key in person) {
console.log(key, person[key]);
}
// Object.keys()
console.log(Object.keys(person)); // ["name", "age", "city"]
// Object.values()
console.log(Object.values(person)); // ["张三", 25, "北京"]
// Object.entries()
console.log(Object.entries(person)); // [["name", "张三"], ["age", 25], ["city", "北京"]]
// Object.fromEntries()
const entries = [["name", "张三"], ["age", 25]];
console.log(Object.fromEntries(entries)); // { name: "张三", age: 25 }6. 对象解构
javascript
const person = { name: "张三", age: 25, city: "北京" };
// 基本解构
const { name, age } = person;
// 重命名
const { name: userName, age: userAge } = person;
// 默认值
const { name, country = "中国" } = person;
// 嵌套解构
const user = {
name: "张三",
address: {
city: "北京",
street: "长安街"
}
};
const {
address: { city }
} = user;
// 解构剩余属性
const { name: userName, ...rest } = person;
console.log(rest); // { age: 25, city: "北京" }7. 对象展开
javascript
const person = { name: "张三", age: 25 };
// 合并对象
const newPerson = { ...person, city: "北京" };
console.log(newPerson); // { name: "张三", age: 25, city: "北京" }
// 修改属性
const updatedPerson = { ...person, age: 26 };
console.log(updatedPerson); // { name: "张三", age: 26 }
// Object.assign
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = Object.assign({}, obj1, obj2);
console.log(merged); // { a: 1, b: 2 }二、数组(Array)
1. 创建数组
javascript
// 数组字面量
const arr1 = [1, 2, 3];
const arr2 = ["张三", "李四", "王五"];
const arr3 = [1, "hello", true, { name: "张三" }];
// Array 构造函数
const arr4 = new Array(1, 2, 3);
const arr5 = new Array(5); // 创建 5 个空元素
// Array.from
const arr6 = Array.from("hello");
console.log(arr6); // ["h", "e", "l", "l", "o"]
// Array.of
const arr7 = Array.of(1, 2, 3);2. 访问元素
javascript
const arr = ["张三", "李四", "王五", "赵六"];
// 下标访问(从 0 开始)
console.log(arr[0]); // "张三"
console.log(arr[1]); // "李四"
// at()(负索引)
console.log(arr.at(-1)); // "赵六"
console.log(arr.at(-2)); // "王五"
// length 属性
console.log(arr.length); // 43. 添加/删除元素
javascript
const arr = ["张三", "李四"];
// push(末尾添加)
arr.push("王五"); // arr: ["张三", "李四", "王五"]
// pop(末尾删除)
arr.pop(); // arr: ["张三", "李四"]
// unshift(头部添加)
arr.unshift("王五"); // arr: ["王五", "张三", "李四"]
// shift(头部删除)
arr.shift(); // arr: ["张三", "李四"]
// splice(任意位置添加/删除)
arr.splice(1, 0, "王五"); // 在索引 1 添加,返回空数组
arr.splice(1, 1); // 删除索引 1 的元素,返回 ["王五"]
arr.splice(0, 2, "新增"); // 删除 2 个,添加 1 个4. 查找元素
javascript
const arr = [
{ id: 1, name: "张三" },
{ id: 2, name: "李四" },
{ id: 3, name: "王五" }
];
// indexOf(查找下标)
const index = arr.indexOf("张三"); // 0
// includes(是否存在)
const exists = arr.includes("张三"); // true
// find(查找元素)
const found = arr.find(item => item.id === 2);
console.log(found); // { id: 2, name: "李四" }
// findIndex(查找下标)
const foundIndex = arr.findIndex(item => item.id === 2);
console.log(foundIndex); // 15. 遍历数组
javascript
const arr = [1, 2, 3, 4, 5];
// forEach
arr.forEach((item, index) => {
console.log(index, item);
});
// for...of
for (const item of arr) {
console.log(item);
}
// for...in(不推荐)
for (const index in arr) {
console.log(index, arr[index]);
}
// map
const doubled = arr.map(item => item * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter
const evens = arr.filter(item => item % 2 === 0);
console.log(evens); // [2, 4]
// reduce
const sum = arr.reduce((total, item) => total + item, 0);
console.log(sum); // 15
// some(是否有一个满足)
const hasEven = arr.some(item => item % 2 === 0);
console.log(hasEven); // true
// every(是否都满足)
const allPositive = arr.every(item => item > 0);
console.log(allPositive); // true6. 数组解构
javascript
const arr = ["张三", "李四", "王五", "赵六"];
// 基本解构
const [first, second] = arr;
// 跳过元素
const [, , third] = arr; // "王五"
// 剩余元素
const [first, ...rest] = arr;
console.log(rest); // ["李四", "王五", "赵六"]
// 默认值
const [a, b, c, d, e = "默认值"] = arr;
console.log(e); // "赵六"
// 交换变量
let x = 1, y = 2;
[x, y] = [y, x];
console.log(x, y); // 2, 17. 数组其他方法
javascript
const arr = [3, 1, 4, 1, 5, 9, 2, 6];
// sort(排序)
arr.sort(); // [1, 1, 2, 3, 4, 5, 6, 9]
arr.sort((a, b) => a - b); // 数字排序(升序)
arr.sort((a, b) => b - a); // 数字排序(降序)
// reverse(反转)
arr.reverse();
// concat(合并)
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = arr1.concat(arr2); // [1, 2, 3, 4, 5, 6]
// slice(切片)
const arr = [1, 2, 3, 4, 5];
const sliced = arr.slice(1, 3); // [2, 3]
// join(转字符串)
const arr = ["张三", "李四", "王五"];
const str = arr.join(", "); // "张三, 李四, 王五"
// toString
console.log(arr.toString()); // "张三,李四,王五"
// flat(扁平化)
const nested = [1, [2, [3, [4]]]];
const flat = nested.flat(2); // [1, 2, 3, [4]]
const completelyFlat = nested.flat(Infinity); // [1, 2, 3, 4]
// isArray
console.log(Array.isArray([1, 2, 3])); // true三、对象与数组常用技巧
1. 深拷贝
javascript
// JSON 方法(简单但有限制)
const original = { name: "张三", age: 25 };
const copy = JSON.parse(JSON.stringify(original));
// 结构化克隆(现代浏览器)
const copy2 = structuredClone(original);
// Lodash
// const copy3 = _.cloneDeep(original);2. 冻结对象
javascript
const obj = { name: "张三", age: 25 };
Object.freeze(obj);
obj.age = 30; // 不生效(严格模式下报错)
// 判断
console.log(Object.isFrozen(obj)); // true3. 数组去重
javascript
// Set
const arr = [1, 2, 2, 3, 3, 3];
const unique = [...new Set(arr)];
console.log(unique); // [1, 2, 3]
// filter + indexOf
const unique2 = arr.filter((item, index) => arr.indexOf(item) === index);4. 数组转对象
javascript
const arr = [
["name", "张三"],
["age", 25]
];
const obj = Object.fromEntries(arr);
console.log(obj); // { name: "张三", age: 25 }四、总结
- 对象用于存储键值对数据
- 数组用于存储有序数据
- 解构和展开让代码更简洁
- 熟练掌握常用方法能提高开发效率