对象创建与属性
2025年3月7日大约 5 分钟
对象创建与属性
JavaScript提供了多种创建对象的方式,包括对象字面量、构造函数和Object.create()等。本文将详细介绍这些创建方式的语法和特点,以及如何定义、访问和修改对象的属性。
创建对象的方法
1. 对象字面量
最简单和常用的创建对象方式是使用对象字面量语法:
// 基本语法
const person = {
name: '张三',
age: 30,
sayHello() {
console.log(`你好,我是${this.name}`);
}
};
// 使用计算属性名
const propertyName = 'age';
const user = {
name: '李四',
[propertyName]: 25 // 使用变量作为属性名
};
// 属性值简写
const name = '王五';
const age = 35;
const employee = {
name, // 等同于 name: name
age // 等同于 age: age
};
2. 构造函数
使用构造函数可以创建具有相同属性和方法的多个对象:
// 自定义构造函数
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
console.log(`你好,我是${this.name}`);
};
}
// 创建实例
const person1 = new Person('张三', 30);
const person2 = new Person('李四', 25);
console.log(person1.name); // '张三'
person2.sayHello(); // '你好,我是李四'
// 内置构造函数
const obj1 = new Object();
const arr = new Array();
const date = new Date();
3. Object.create()
使用Object.create()
方法可以基于现有对象创建新对象:
// 创建原型对象
const personProto = {
sayHello() {
console.log(`你好,我是${this.name}`);
}
};
// 基于原型创建新对象
const person = Object.create(personProto);
person.name = '张三';
person.age = 30;
person.sayHello(); // '你好,我是张三'
// 创建没有原型的对象
const noProtoObj = Object.create(null);
console.log(noProtoObj.__proto__); // undefined
对象属性操作
1. 访问属性
可以使用点号或方括号语法访问对象属性:
const person = {
name: '张三',
age: 30,
'full-name': '张三丰' // 包含特殊字符的属性名
};
// 点号语法
console.log(person.name); // '张三'
console.log(person.age); // 30
// 方括号语法
console.log(person['name']); // '张三'
console.log(person['full-name']); // '张三丰'
// 使用变量访问
const propertyName = 'age';
console.log(person[propertyName]); // 30
2. 添加和修改属性
const person = {
name: '张三'
};
// 添加新属性
person.age = 30;
person['occupation'] = '工程师';
// 修改现有属性
person.name = '张三丰';
person['age'] = 31;
// 添加方法
person.sayHello = function() {
console.log(`你好,我是${this.name}`);
};
console.log(person);
// {
// name: '张三丰',
// age: 31,
// occupation: '工程师',
// sayHello: [Function]
// }
3. 删除属性
使用delete
运算符可以删除对象的属性:
const person = {
name: '张三',
age: 30,
occupation: '工程师'
};
// 删除属性
delete person.age;
delete person['occupation'];
console.log(person); // { name: '张三' }
属性描述符
JavaScript允许我们精确控制对象属性的行为:
1. 获取属性描述符
const person = {
name: '张三'
};
const descriptor = Object.getOwnPropertyDescriptor(person, 'name');
console.log(descriptor);
// {
// value: '张三',
// writable: true,
// enumerable: true,
// configurable: true
// }
2. 定义属性
使用Object.defineProperty()
可以精确定义属性:
const person = {};
// 定义单个属性
Object.defineProperty(person, 'name', {
value: '张三',
writable: true, // 是否可修改
enumerable: true, // 是否可枚举
configurable: true // 是否可配置(删除、修改特性)
});
// 定义多个属性
Object.defineProperties(person, {
age: {
value: 30,
writable: true
},
occupation: {
value: '工程师',
writable: false // 只读属性
}
});
3. 访问器属性
可以使用getter和setter定义计算属性:
const person = {
firstName: '三',
lastName: '张',
// getter
get fullName() {
return this.lastName + this.firstName;
},
// setter
set fullName(value) {
[this.lastName, this.firstName] = value.split(' ');
}
};
console.log(person.fullName); // '张三'
person.fullName = '李 四';
console.log(person.firstName); // '四'
console.log(person.lastName); // '李'
属性特性
每个属性都有以下特性:
1. 数据属性
value
:属性的值writable
:是否可修改enumerable
:是否可枚举configurable
:是否可配置
const person = {};
Object.defineProperty(person, 'name', {
value: '张三',
writable: false, // 不可修改
enumerable: true, // 可枚举
configurable: false // 不可配置
});
// 尝试修改只读属性
person.name = '李四';
console.log(person.name); // 仍然是'张三'
// 尝试删除不可配置的属性
delete person.name; // 操作无效
console.log(person.name); // '张三'
2. 访问器属性
get
:获取属性值的函数set
:设置属性值的函数enumerable
:是否可枚举configurable
:是否可配置
const person = {
_age: 30
};
Object.defineProperty(person, 'age', {
get() {
return this._age;
},
set(value) {
if (value >= 0 && value <= 150) {
this._age = value;
} else {
throw new Error('年龄必须在0-150之间');
}
},
enumerable: true,
configurable: true
});
person.age = 31; // 正常设置
console.log(person.age); // 31
try {
person.age = -1; // 抛出错误
} catch (e) {
console.error(e.message); // "年龄必须在0-150之间"
}
对象属性的遍历
有多种方法可以遍历对象的属性:
const person = {
name: '张三',
age: 30,
occupation: '工程师'
};
// 1. for...in 循环
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
// 2. Object.keys()
Object.keys(person).forEach(key => {
console.log(`${key}: ${person[key]}`);
});
// 3. Object.values()
Object.values(person).forEach(value => {
console.log(value);
});
// 4. Object.entries()
Object.entries(person).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
对象属性的检测
1. 检查属性是否存在
const person = {
name: '张三',
age: 30,
sayHello() {
console.log('你好');
}
};
// 使用in运算符
console.log('name' in person); // true
console.log('toString' in person); // true(继承的属性)
// 使用hasOwnProperty()方法
console.log(person.hasOwnProperty('name')); // true
console.log(person.hasOwnProperty('toString')); // false
// 使用可选链操作符(?.)
console.log(person?.name); // '张三'
console.log(person?.address); // undefined
2. 属性值的检查
const person = {
name: '张三',
age: undefined,
occupation: null
};
// 直接比较undefined
console.log(person.name === undefined); // false
console.log(person.age === undefined); // true
console.log(person.address === undefined); // true
// 使用typeof
console.log(typeof person.name); // 'string'
console.log(typeof person.age); // 'undefined'
console.log(typeof person.occupation); // 'object'
// 检查null
console.log(person.occupation === null); // true
最佳实践
- 使用对象字面量:对于简单对象,优先使用对象字面量语法。
- 使用构造函数:当需要创建多个相似对象时,使用构造函数。
- 使用Object.create():当需要明确指定对象原型时,使用Object.create()。
- 属性访问:优先使用点号语法,只在属性名包含特殊字符或使用变量时使用方括号语法。
- 属性描述符:谨慎使用不可写和不可配置的属性,它们可能导致代码难以维护。
- 属性检查:使用可选链操作符(?.)进行安全的属性访问。
通过掌握这些对象创建和属性操作的方法,您可以更好地组织和管理JavaScript代码中的数据结构。