文章目录

JavaScript 对象操作:添加、删除、修改属性

发布于 2026-04-05 18:51:45 · 浏览 10 次 · 评论 0 条

JavaScript 对象操作:添加、删除、修改属性

JavaScript 中的对象是存储数据的核心容器,几乎所有编程场景都会用到它。掌握对象的增删改查操作,是写出高效代码的基础。本文将用最直白的方式,带你彻底搞懂 JavaScript 对象的属性操作。


对象的创建方式

在动手操作属性之前,先快速回顾几种常见的对象创建方法。

字面量创建

这是最常用的方式,直接用花括号定义:

const user = {
  name: '张三',
  age: 25
};

构造函数创建

使用 new Object() 语法,功能与字面量完全一致:

const car = new Object();
car.brand = '丰田';
car.color = '白色';

Object.create() 创建

这种方法可以指定一个对象作为原型:

const prototype = {
  greet() {
    return '你好';
  }
};

const person = Object.create(prototype);
person.name = '李四';

添加属性

向 JavaScript 对象添加属性有多种方式,每种方式都有其适用场景。

点符号添加

使用点语法是最直观的方式,适合属性名是合法标识符的情况:

const book = {};
book.title = 'JavaScript高级程序设计';
book.author = 'Nicholas Zakas';
book.year = 2021;

注意:点符号后面的属性名不能以数字开头,不能包含空格或特殊字符(除了 $_)。

方括号添加

当属性名不符合标识符规则,或者属性名是变量时,必须使用方括号:

const config = {};
config['server-url'] = 'https://api.example.com';
config['max-connections'] = 100;

// 使用变量作为属性名
const propName = 'status';
config[propName] = 'active';

方括号内可以放任何表达式,计算结果会作为属性名:

const keys = ['a', 'b', 'c'];
const obj = {};

keys.forEach((key, index) => {
  obj[key] = index * 10;
});
// 结果: { a: 0, b: 10, c: 20 }

批量添加属性

使用 Object.assign() 可以一次性添加多个属性:

const base = { x: 1 };
Object.assign(base, { y: 2 }, { z: 3, x: 10 });
// base 变成 { x: 10, y: 2, z: 3 }

Object.assign() 会修改第一个参数对象,并返回它。如果需要创建新对象,可以这样写:

const original = { a: 1 };
const copy = Object.assign({}, original, { b: 2 });
// original 不变,copy 是 { a: 1, b: 2 }

扩展运算符添加

ES6 提供的扩展运算符是另一种便捷方式:

const obj1 = { a: 1 };
const obj2 = { b: 2 };
const combined = { ...obj1, ...obj2 };
// combined 是 { a: 1, b: 2 }

修改属性

修改属性的本质是给已有属性重新赋值,语法与添加完全相同。

直接赋值修改

const user = { name: '王五', age: 30 };
user.age = 31;
user.name = '王六';
// user 现在是 { name: '王六', age: 31 }

条件修改

有时需要根据当前值决定如何修改,可以使用三元运算符或逻辑运算符:

const counter = { value: 0 };
counter.value = counter.value < 10 ? counter.value + 1 : 0;
// 如果值小于10则加1,否则归零

基于现有值修改

对于数值类型,可以直接使用复合赋值运算符:

const point = { x: 10, y: 20 };
point.x += 5;   // point.x 变成 15
point.y *= 2;   // point.y 变成 40

修改嵌套属性

访问嵌套对象时,直接赋值会触发错误(如果中间属性不存在),所以需要先确保路径存在:

const settings = {
  theme: { colors: { primary: 'blue' } }
};

// 安全修改嵌套属性
settings.theme.colors.primary = 'green';

// 如果不确定结构是否存在,先创建
const data = {};
((data.options || {}).display || {}).title = '新标题';
// 或者使用可选链
data.options?.display?.title = '新标题';

删除属性

删除对象属性使用 delete 运算符,返回布尔值表示是否成功删除。

基本删除语法

const item = { name: '商品', price: 99, stock: 50 };
const result = delete item.price;
// result 是 true,item 变成 { name: '商品', stock: 50 }

注意delete 只能删除对象自身的属性,无法删除原型链上的属性。

删除不存在的属性

删除不存在的属性不会报错,返回 true

const obj = { a: 1 };
delete obj.b;  // 返回 true,不报错

批量删除属性

JavaScript 没有直接的批量删除方法,可以通过解构赋值配合展开运算符实现:

const data = { a: 1, b: 2, c: 3, d: 4, e: 5 };
const { a, e, ...remaining } = data;
// a: 1, e: 5, remaining 是 { b: 2, c: 3, d: 4 }

或者用循环逐个删除:

const obj = { x: 1, y: 2, z: 3 };
const keysToDelete = ['x', 'z'];

keysToDelete.forEach(key => delete obj[key]);
// obj 现在是 { y: 2 }

访问属性的方法

除了点语法和方括号语法,还有几种访问属性的专业方式。

in 运算符检查属性存在

const obj = { a: 1, b: 2 };
'a' in obj;       // true
'c' in obj;       // false

in 会检查对象自身的属性和原型链上的属性。如果只想检查自身属性,用 hasOwnProperty()

const obj = { a: 1 };
obj.hasOwnProperty('a');  // true
obj.hasOwnProperty('toString');  // false(来自原型)

可选链操作符安全访问

当不确定嵌套结构是否存在时,用 ?. 避免报错:

const user = {};
user.address?.city;  // undefined,不会报错
user.address?.city?.name;  // undefined

获取所有属性名

方法 返回内容 自身属性 可枚举 Symbol 属性
Object.keys() 字符串数组
Object.getOwnPropertyNames() 字符串数组 是/否都包含
Object.getOwnPropertySymbols() Symbol 数组 是/否都包含
Reflect.ownKeys() 所有属性名数组 是/否都包含
const obj = { a: 1 };
Object.keys(obj);                      // ['a']
Object.getOwnPropertyNames(obj);       // ['a']

属性描述符:精细控制属性行为

每个对象属性除了值之外,还有着一系列描述其行为的特性。通过属性描述符,可以精确控制属性的可写性、可枚举性等。

获取属性描述符

const obj = { name: '测试' };
const descriptor = Object.getOwnPropertyDescriptor(obj, 'name');
/*
descriptor 结果:
{
  value: '测试',
  writable: true,      // 是否可修改值
  enumerable: true,    // 是否可被遍历
  configurable: true   // 是否可被删除或修改描述符
}
*/

定义属性描述符

使用 Object.defineProperty()Object.defineProperties() 可以精确控制属性:

const obj = {};

// 定义一个只读属性
Object.defineProperty(obj, 'PI', {
  value: 3.14159,
  writable: false,
  enumerable: true,
  configurable: false
});

obj.PI = 100;      // 静默失败,在严格模式下报错
obj.PI;            // 仍然是 3.14159

三个关键特性说明

特性 作用 默认值(字面量创建) 默认值(defineProperty)
writable 控制是否可修改值 true false
enumerable 控制是否可被 for...in / Object.keys 遍历 true false
configurable 控制是否可被删除或重新配置 true false

创建只存不取的属性

通过省略 get 函数并设置 writable: false,可以创建一个无法读取(返回 undefined)的属性:

const obj = {};
Object.defineProperty(obj, 'secret', {
  value: '123456',
  writable: false,
  enumerable: false,
  configurable: false
});

console.log(obj.secret);  // undefined
console.log('secret' in obj);  // true

常见问题与解决方案

问题一:对象属性顺序

现代 JavaScript 中,整数索引属性会按数值大小排序,字符串和 Symbol 属性按创建顺序排序:

const obj = {};
obj[10] = '整数10';
obj[2] = '整数2';
obj.b = '字符串b';
obj.a = '字符串a';
obj[Symbol('s')] = 'Symbol';

Object.keys(obj);  // ['2', '10', 'b', 'a'](整数索引排在前面,按数值排序)

问题二:冻结与密封

如果需要防止对象被意外修改,可以使用以下方法:

方法 禁止添加新属性 禁止删除现有属性 禁止修改属性值 禁止修改描述符
Object.freeze()
Object.seal()
Object.preventExtensions()
const obj = { a: 1 };
Object.freeze(obj);
obj.a = 100;       // 无效
obj.b = 2;         // 无效
delete obj.a;      // 无效

问题三:浅拷贝与深拷贝

直接赋值或展开运算符都是浅拷贝,只复制第一层:

const original = { a: 1, nested: { b: 2 } };
const shallow = { ...original };
shallow.nested.b = 100;
original.nested.b;  // 100,也被修改了

深拷贝需要递归处理或使用结构化克隆:

// 方法一:JSON 序列化(简单场景)
const deep = JSON.parse(JSON.stringify(original));

// 方法二:结构化克隆(支持更多类型)
const deep2 = structuredClone(original);

实战示例

假设你需要实现一个配置管理功能,包含默认值、运行时修改、以及防止意外修改的需求:

class Config {
  constructor(defaults) {
    this._data = { ...defaults };

    // 将所有默认属性设为不可枚举
    Object.keys(this._data).forEach(key => {
      Object.defineProperty(this, key, {
        get() { return this._data[key]; },
        set(value) { this._data[key] = value; },
        enumerable: true,
        configurable: false
      });
    });
  }

  get(key) {
    return this._data[key];
  }

  set(key, value) {
    this._data[key] = value;
  }

  freeze() {
    Object.freeze(this._data);
  }
}

// 使用示例
const config = new Config({ theme: 'dark', language: 'zh-CN' });
config.language = 'en';        // 修改成功
config.theme;                  // 'dark'
config.freeze();               // 冻结后无法再修改

这篇文章涵盖了 JavaScript 对象属性操作的核心知识点。理解这些基础概念,你就能在实际开发中游刃有余地处理各种对象操作场景。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文