← JavaScript函数 bind() JavaScript数组 →

JavaScript对象

原创 2026-03-13 JavaScript 已有人查阅

JavaScript对象指南:从基础概念到内置方法详解

什么是JavaScript对象?

在JavaScript中,对象是一种复合数据类型,可以容纳多个值。可以把对象想象成一个容器,里面存放着相关的数据和功能。对象是JavaScript中最基础的数据类型之一,几乎everything in JavaScript is an object或可以表现为对象。

生活类比
想象一辆汽车。汽车有颜色、品牌、型号、价格等属性,还能启动、加速、刹车。在这类比中:

  • 汽车本身就是一个对象

  • 颜色、品牌、型号是对象的属性(Properties)

  • 启动、加速、刹车是对象的方法(Methods)

// 汽车对象的JavaScript表示
let car = {
    brand: '丰田',
    model: '凯美瑞',
    color: '黑色',
    price: 240000,
    
    // 方法
    start: function() {
        console.log('汽车启动');
    },
    
    accelerate: function() {
        console.log('汽车加速');
    }
};

对象的语法结构

对象字面量语法

const objectName = {
    key1: value1,
    key2: value2,
    key3: value3
};

语法说明:

  • 使用花括号 {} 定义对象的开始和结束

  • 内部包含多个键值对,用逗号分隔

  • 每个键后面跟冒号 :,然后是值

  • 值可以是任何数据类型:字符串、数字、布尔值、数组、函数、甚至他对象

创建对象的多种方式

1. 对象字面量(最常用)

// 最简单的对象创建方式
let student = {
    name: '张三',
    age: 20,
    major: '计算机科学',
    scores: [85, 92, 78],
    introduce: function() {
        console.log(`我叫${this.name},今年${this.age}岁`);
    }
};

student.introduce();  // 我叫张三,今年20岁

个人经验:对象字面量是我日常开发中使用最多的方式,简洁直观,适合创建单一对象实例。

2. 使用new关键字

// 创建空对象再添加属性
let person = new Object();
person.name = '李四';
person.age = 25;
person.job = '工程师';
person.sayHi = function() {
    console.log('你好,我是' + this.name);
};

person.sayHi();  // 你好,我是李四

3. 构造函数模式

// 定义构造函数
function Student(name, age, major) {
    this.name = name;
    this.age = age;
    this.major = major;
    this.introduce = function() {
        console.log(`${this.name},${this.age}岁,专业:${this.major}`);
    };
}

// 创建多个实例
let student1 = new Student('王五', 22, '软件工程');
let student2 = new Student('赵六', 21, '数据科学');

student1.introduce();  // 王五,22岁,专业:软件工程
student2.introduce();  // 赵六,21岁,专业:数据科学

个人见解:构造函数适合需要创建多个相似对象的场景,比重复写对象字面量更高效。

4. Object.create()方法

// 原型对象
let animal = {
    type: '动物',
    speak: function() {
        console.log(this.name + '发出声音');
    }
};

// 基于原型创建新对象
let dog = Object.create(animal);
dog.name = '旺财';
dog.breed = '金毛';
dog.speak();  // 旺财发出声音

let cat = Object.create(animal);
cat.name = '';
cat.speak();  // 发出声音

JavaScript对象的可变性

对象与原始类型较大的区别在于:对象是可变的(Mutable)

let user = {
    username: 'alex',
    age: 28,
    email: 'alex@example.com'
};

console.log('原始对象:', user);

// 修改现有属性
user.age = 29;
console.log('修改后:', user);  // age变为29

// 添加新属性
user.phone = '13800138000';
console.log('添加后:', user);  // 新增phone属性

// 删除属性
delete user.email;
console.log('删除后:', user);  // email属性被移除

// 对象本身不变,但内容变了
console.log('对象引用不变,内容已变');

为什么可变性很重要?
当对象被传递给函数时,传递的是引用,函数内部修改会影响原对象:

function updateAge(person) {
    person.age += 1;  // 直接修改原对象
    console.log('函数内部:', person.age);
}

let user2 = { name: '张三', age: 25 };
console.log('调用前:', user2.age);  // 25
updateAge(user2);                     // 函数内部:26
console.log('调用后:', user2.age);   // 26(原对象被修改)

对象的属性操作

访问属性

let book = {
    title: 'JavaScript高级程序设计',
    author: 'Nicholas',
    'publication-year': 2024,
    price: 99
};

// 点号语法(常用)
console.log(book.title);     // JavaScript高级程序设计
console.log(book.author);    // Nicholas

// 方括号语法(处理特殊属性名)
console.log(book['publication-year']);  // 2024

// 变量作为属性名
let prop = 'price';
console.log(book[prop]);  // 99

遍历对象属性

let product = {
    name: '笔记本电脑',
    brand: '联想',
    price: 5999,
    inStock: true
};

// 使用for...in循环
for (let key in product) {
    console.log(`${key}: ${product[key]}`);
}
// 输出:
// name: 笔记本电脑
// brand: 联想
// price: 5999
// inStock: true

// 使用Object.keys()获取所有键
console.log(Object.keys(product));   // ['name', 'brand', 'price', 'inStock']

// 使用Object.values()获取所有值
console.log(Object.values(product)); // ['笔记本电脑', '联想', 5999, true]

// 使用Object.entries()获取键值对数组
console.log(Object.entries(product));
// [['name', '笔记本电脑'], ['brand', '联想'], ['price', 5999], ['inStock', true]]

常用的内置对象方法

1. Object.create() - 基于原型创建对象

const personPrototype = {
    greet: function() {
        console.log(`你好,我是${this.name}`);
    },
    is: function() {
        return this.age >= 18;
    }
};

let employee = Object.create(personPrototype, {
    name: { value: '李华', writable: true },
    age: { value: 28, writable: true },
    job: { value: '工程师', writable: true },
    salary: { value: 15000, writable: true }
});

employee.greet();          // 你好,我是李华
console.log(employee.is());  // true
console.log(employee.job);        // 工程师

2. Object.entries() - 获取键值对数组

const user = {
    id: 1001,
    username: 'alex123',
    email: 'alex@example.com',
    active: true
};

const entries = Object.entries(user);
console.log(entries);
// [['id', 1001], ['username', 'alex123'], ['email', 'alex@example.com'], ['active', true]]

// 实用场景:将对象转换为URL参数
function objectToQueryString(obj) {
    return Object.entries(obj)
        .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
        .join('&');
}

console.log(objectToQueryString(user));
// id=1001&username=alex123&email=alex%40example.com&active=true

3. Object.keys() - 获取所有属性名

const settings = {
    theme: 'dark',
    fontSize: 14,
    showNotifications: true,
    language: 'zh-CN'
};

console.log(Object.keys(settings));  // ['theme', 'fontSize', 'showNotifications', 'language']

// 实用场景:检查对象是否为空
function isEmpty(obj) {
    return Object.keys(obj).length === 0;
}

console.log(isEmpty({}));        // true
console.log(isEmpty({a: 1}));    // false

4. Object.values() - 获取所有属性值

const scores = {
    math: 95,
    english: 88,
    physics: 92,
    chemistry: 85
};

const values = Object.values(scores);
console.log(values);  // [95, 88, 92, 85]

// 计算平均分
const average = values.reduce((sum, score) => sum + score, 0) / values.length;
console.log('平均分:', average.toFixed(2));  // 平均分:90.00

5. Object.is() - 严格相等比较

console.log(Object.is(25, 25));           // true
console.log(Object.is('hello', 'hello')); // true
console.log(Object.is(true, false));      // false

// 特殊情况的处理
console.log(Object.is(0, -0));             // false(区分正负零)
console.log(0 === -0);                      // true(三等号不区分)

console.log(Object.is(NaN, NaN));           // true
console.log(NaN === NaN);                    // false(三等号认为NaN不等于自身)

6. Object.assign() - 对象合并与复制

// 合并多个对象
const defaults = {
    theme: 'light',
    fontSize: 12,
    showSidebar: true
};

const userConfig = {
    fontSize: 16,
    language: 'en'
};

const finalConfig = Object.assign({}, defaults, userConfig);
console.log(finalConfig);
// {theme: 'light', fontSize: 16, showSidebar: true, language: 'en'}

// 浅拷贝对象
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);

console.log(copy);           // {a: 1, b: {c: 2}}
console.log(copy === original);  // false(不同对象)

// 注意:Object.assign是浅拷贝
copy.b.c = 100;
console.log(original.b.c);  // 100(原对象也被修改)

7. Object.freeze() - 冻结对象

const CONFIG = {
    apiUrl: 'https://api.example.com',
    version: '1.0.0',
    maxRetries: 3
};

Object.freeze(CONFIG);

// 尝试修改(严格模式下会报错,非严格模式静默失败)
CONFIG.version = '2.0.0';        // 无效
CONFIG.newProperty = 'test';      // 无效
delete CONFIG.maxRetries;         // 无效

console.log(CONFIG);  // 原对象不变

// 检查对象是否冻结
console.log(Object.isFrozen(CONFIG));  // true

8. Object.seal() - 密封对象

const userProfile = {
    name: '张三',
    age: 30,
    email: 'zhangsan@example.com'
};

Object.seal(userProfile);

// 可以修改现有属性
userProfile.age = 31;
console.log(userProfile.age);  // 31

// 不能添加新属性
userProfile.phone = '123456789';  // 无效
console.log(userProfile.phone);   // undefined

// 不能删除属性
delete userProfile.email;         // 无效
console.log(userProfile.email);   // zhangsan@example.com

// 检查对象是否密封
console.log(Object.isSealed(userProfile));  // true

对象属性的高级特性

属性描述符

let person = {
    name: '李华'
};

// 获取属性描述符
let descriptor = Object.getOwnPropertyDescriptor(person, 'name');
console.log(descriptor);
// {value: '李华', writable: true, enumerable: true, configurable: true}

// 定义具有特定属性的属性
Object.defineProperty(person, 'age', {
    value: 25,
    writable: false,     // 不可修改
    enumerable: true,    // 可枚举
    configurable: false  // 不可配置(不能删除,不能修改描述符)
});

person.age = 30;  // 无效(因为writable为false)
console.log(person.age);  // 25

delete person.age;  // 无效(因为configurable为false)
console.log(person.age);  // 25

课程知识要点

  1. 对象定义:JavaScript对象是键值对的,可以包含各种数据类型

  2. 创建方式:对象字面量、new Object()、构造函数、Object.create()

  3. 可变特性:对象是引用类型,内容可以修改,传递的是引用

  4. 属性操作:点号语法、方括号语法、添加、修改、删除属性

  5. 遍历方法:for...in、Object.keys()、Object.values()、Object.entries()

  6. 对象比较:Object.is()提供严格的相等比较,区分NaN和±0

  7. 对象合并:Object.assign()用于浅拷贝和合并对象

  8. 对象控制:Object.freeze()冻结、Object.seal()密封、Object.defineProperty()精细控制

  9. 原型继承:Object.create()基于原型创建对象

开发实践建议

基于多年JavaScript开发经验,我对对象使用的建议如下:

推荐做法:

  • 创建单个对象优先使用对象字面量 {}

  • 需要多个同类对象使用构造函数或class

  • 使用Object.freeze()保护配置对象

  • 使用解构赋值获取对象属性

  • 使用可选链操作符.安全访问嵌套属性

// 现在JavaScript对象操作示例
class User {
    constructor(data) {
        this.id = data.id;
        this.name = data.name;
        this.email = data.email;
        this.createdAt = data.createdAt || new Date();
    }
    
    get info() {
        return `${this.name} (${this.email})`;
    }
    
    update(data) {
        Object.assign(this, data);
    }
}

// 使用示例
const userData = {
    id: 1001,
    name: '王小明',
    email: 'wang@example.com'
};

const user = new User(userData);
console.log(user.info);  // 王小明 (wang@example.com)

user.update({ name: '王晓明' });
console.log(user.name);  // 王晓明

// 安全访问嵌套属性
const response = {
    data: {
        user: {
            profile: {
                displayName: '小明同学'
            }
        }
    }
};

// 传统方式(报错)
// const name = response.data.user.profile.displayName;

// 现在安全方式
const displayName = response.data.user.profile.displayName  '匿名';
console.log(displayName);  // 小明同学

对象是JavaScript的核心,深入理解对象及方法,是写出高质量代码的基础。掌握这些知识,你就能更好地组织数据、构建复杂的应用逻辑。

← JavaScript函数 bind() JavaScript数组 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号