对象基础
JavaScript中的对象是一种复合数据类型,用于存储键值对的集合。它不仅是语言的核心概念,还提供了灵活的数据组织和操作方式。理解对象的基础特性对编写高效代码至关重要。
对象的基本结构
对象由属性和方法构成,属性是键值对,键通常是字符串或Symbol类型,值可以是任意数据类型。方法则是函数类型的属性。对象字面量是最常见的创建方式:
const person = {
name: '张三',
age: 30,
greet: function() {
console.log(`你好,我是${this.name}`);
}
};
通过点表示法或方括号可以访问属性:
console.log(person.name); // "张三"
console.log(person['age']); // 30
person.greet(); // 调用方法
动态属性操作
JavaScript允许运行时动态添加或删除属性:
// 添加新属性
person.job = '工程师';
// 删除属性
delete person.age;
// 检查属性存在性
'name' in person; // true
使用Object.keys()
可获取所有可枚举属性:
const keys = Object.keys(person); // ["name", "greet", "job"]
构造函数与实例
通过构造函数可以创建多个相似对象:
function Book(title, author) {
this.title = title;
this.author = author;
this.getInfo = function() {
return `${this.title} - ${this.author}`;
};
}
const book1 = new Book('JavaScript高级编程', 'Nicholas');
console.log(book1.getInfo());
原型继承机制
每个JavaScript对象都有原型链,用于实现继承:
Book.prototype.discount = function(percent) {
return `本书享受${percent}%折扣`;
};
console.log(book1.discount(20)); // 调用原型方法
使用Object.create()
可显式设置原型:
const animal = { eats: true };
const rabbit = Object.create(animal);
console.log(rabbit.eats); // true
对象解构赋值
ES6引入的解构语法简化了对象属性提取:
const { name, job } = person;
console.log(name, job); // "张三" "工程师"
// 嵌套解构
const user = {
id: 1,
profile: {
name: '李四',
address: '北京'
}
};
const { profile: { address } } = user;
console.log(address); // "北京"
对象属性描述符
通过属性描述符可以控制属性行为:
Object.defineProperty(person, 'gender', {
value: 'male',
writable: false, // 不可写
enumerable: true // 可枚举
});
// 尝试修改会静默失败(严格模式会报错)
person.gender = 'female';
console.log(person.gender); // 仍为"male"
获取完整描述符:
const desc = Object.getOwnPropertyDescriptor(person, 'name');
/*
{
value: "张三",
writable: true,
enumerable: true,
configurable: true
}
*/
对象冻结与密封
JavaScript提供了三种限制对象修改的方式:
const obj = { prop: 42 };
// 1. 防止扩展
Object.preventExtensions(obj);
obj.newProp = 'test'; // 静默失败
// 2. 密封对象(不能添加/删除属性)
Object.seal(obj);
delete obj.prop; // 静默失败
// 3. 冻结对象(完全不可变)
Object.freeze(obj);
obj.prop = 999; // 静默失败
ES6类语法糖
class语法提供了更清晰的面向对象写法:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter方法
get area() {
return this.calcArea();
}
// 实例方法
calcArea() {
return this.height * this.width;
}
// 静态方法
static createSquare(side) {
return new Rectangle(side, side);
}
}
const rect = new Rectangle(10, 5);
console.log(rect.area); // 50
const square = Rectangle.createSquare(10);
对象迭代方式
ES6新增了多种对象迭代方法:
const scores = { math: 90, science: 85, history: 88 };
// 1. Object.keys()
for (const key of Object.keys(scores)) {
console.log(key);
}
// 2. Object.values()
console.log(Object.values(scores)); // [90, 85, 88]
// 3. Object.entries()
for (const [subject, score] of Object.entries(scores)) {
console.log(`${subject}: ${score}`);
}
深拷贝与浅拷贝
对象复制需要特别注意引用问题:
// 浅拷贝
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
shallowCopy.b.c = 99;
console.log(original.b.c); // 99 (被修改)
// 深拷贝方案
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 100;
console.log(original.b.c); // 仍为99
对象与Map比较
ES6的Map在某些场景比对象更适合:
const map = new Map();
map.set('name', '王五');
map.set(1, '数字键');
map.set({}, '对象作为键');
console.log(map.get(1)); // "数字键"
console.log(map.size); // 3
// 对象键不会被转为字符串
const objKey = {};
map.set(objKey, '特殊对象');
console.log(map.get({})); // undefined (不同引用)
console.log(map.get(objKey)); // "特殊对象"
可选链操作符
ES2020引入的可选链简化了深层属性访问:
const company = {
name: 'TechCorp',
departments: {
dev: { size: 50 },
hr: { size: 10 }
}
};
// 传统方式
const devSize = company.departments && company.departments.dev && company.departments.dev.size;
// 可选链方式
const modernDevSize = company.departments?.dev?.size;
console.log(modernDevSize); // 50
// 不存在的属性返回undefined
const salesSize = company.departments?.sales?.size;
console.log(salesSize); // undefined
空值合并运算符
与可选链配合使用的逻辑运算符:
const config = {
timeout: 0,
title: '',
animation: null
};
// 传统默认值设置
const timeout = config.timeout !== undefined ? config.timeout : 1000;
// 空值合并运算符
const modernTimeout = config.timeout ?? 1000;
const title = config.title ?? '默认标题';
const animation = config.animation ?? 'fade';
console.log(modernTimeout); // 0 (0不是null/undefined)
console.log(title); // "" (空字符串不是null/undefined)
console.log(animation); // "fade"
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn