当前位置: 首页 > news >正文

JavaScript 的“世界模型”:深入理解对象 (Objects)

引言:超越简单值,构建复杂实体

到目前为止,我们学习的变量大多存储的是单一的值,比如一个数字 (let age = 30;​)、一个字符串 (let name = "Alice";​) 或一个布尔值 (let isActive = true;​)。这对于简单场景足够了,但现实世界是复杂的。如何表示一个包含多个相关信息的东西,比如一个“用户”?一个用户有名字、年龄、邮箱、地址等等属性。

这就是对象 (Object) 大显身手的地方。在 JavaScript 中,对象是一种复合数据类型,它允许我们将多个键值对 (key-value pairs) 组合在一起,用来描述一个实体(比如一个人、一辆车、一个订单)的特征和行为。

你可以把对象想象成一个现实世界物体的数字模型,或者一个包含各种相关信息的“档案袋”。它是 JavaScript 中组织和管理数据的基本方式,理解它对于后续学习框架、API 交互等至关重要。

准备好探索如何用代码构建你自己的“世界模型”了吗?

一、创建对象:组装你的“档案袋”

创建对象最常用、最直观的方式是使用对象字面量 (Object Literal) 语法,也就是用一对大括号 {}​。

// 创建一个空对象
let emptyObject = {};// 创建一个表示用户的对象
let user = {// 键 (key) : 值 (value)name: "Bob",          // 属性 name,值是字符串 "Bob"age: 28,             // 属性 age,值是数字 28isAdmin: false,       // 属性 isAdmin,值是布尔值 false"e-mail": "bob@example.com", // 键包含特殊字符,必须用引号包裹address: {           // 值可以是另一个对象(嵌套对象)street: "123 Main St",city: "Anytown"},hobbies: ["reading", "music", "hiking"] // 值可以是数组
};
  • 键 (Key)/属性名 (Property Name):

    • 通常是字符串。如果键名符合变量命名规则(不含空格、特殊字符,不以数字开头),则引号可以省略(如 name​, age​)。否则,必须用引号包裹(如 "e-mail"​)。
    • 也可以是 ES6 引入的 Symbol​ 类型。
  • 值 (Value)/属性值 (Property Value):

    • 可以是任何 JavaScript 数据类型:String​, Number​, Boolean​, null​, undefined​, Symbol​, BigInt​, 甚至可以是另一个对象或数组或函数。
  • 键值对: 每个 key: value​ 组合称为对象的一个属性 (Property)。属性之间用逗号 ,​ 分隔。

另一种方式:new Object()​ (不常用)
你也可以使用 new Object()​ 构造函数来创建对象,然后逐个添加属性。但这种方式比较冗长,通常我们优先使用对象字面量。

let car = new Object();
car.make = "Toyota";
car.model = "Camry";
car.year = 2022;

二、访问属性:从“档案袋”里取东西

创建了对象,如何获取里面存储的信息呢?主要有两种方式:

1. 点符号 (Dot Notation): object.propertyName​

这是最常用、最简洁的方式。直接在对象名后面跟一个点 .​,然后是属性名。

console.log(user.name); // 输出: Bob
console.log(user.age);  // 输出: 28
console.log(user.address.city); // 访问嵌套对象的属性: Anytown
console.log(user.hobbies[0]);    // 访问数组属性的元素: reading// console.log(user."e-mail"); // 错误!点符号不能用于带特殊字符的键
  • 限制: 属性名必须是有效的 JavaScript 标识符(不能是纯数字,不能包含空格或特殊字符等)。

2. 方括号符号 (Bracket Notation): object['propertyName']​

这种方式更灵活,方括号 []​ 里面放的是一个字符串(或者能计算出字符串的表达式,比如变量),这个字符串就是你要访问的属性名。

console.log(user['name']);       // 输出: Bob
console.log(user['age']);        // 输出: 28
console.log(user['address']['city']); // 访问嵌套对象
console.log(user['hobbies'][1]); // 访问数组元素: music
console.log(user['e-mail']);     // 正确!可以访问带特殊字符的键// 使用变量作为键名
let propertyToAccess = "isAdmin";
console.log(user[propertyToAccess]); // 输出: false (访问 user['isAdmin'])let keyPart1 = "addr";
let keyPart2 = "ess";
console.log(user[keyPart1 + keyPart2].street); // 输出: 123 Main St (访问 user['address'].street)
  • 优势:

    • 可以访问任何字符串作为键名,包括包含空格、特殊字符、或者以数字开头的键。
    • 可以用变量来动态指定要访问的属性名。

访问不存在的属性:
如果尝试访问一个对象上不存在的属性,不会报错,而是会返回 undefined​。

console.log(user.gender); // 输出: undefined
console.log(user['phone number']); // 输出: undefined

三、修改属性:更新“档案袋”里的信息

对象的属性不是一成不变的,你可以随时修改它们。

1. 更新现有属性:
直接使用点符号或方括号符号,像给变量赋值一样,给属性赋一个新值。

user.age = 29; // 更新 age 属性
user['isAdmin'] = true; // 更新 isAdmin 属性
user.address.city = "New City"; // 更新嵌套对象的属性console.log(user.age);     // 输出: 29
console.log(user.isAdmin); // 输出: true
console.log(user.address.city); // 输出: New City

2. 添加新属性:
如果赋值给一个对象上不存在的属性,JavaScript 会自动为你创建这个新属性。

user.country = "USA"; // 添加新的 country 属性
user['phone number'] = "123-456-7890"; // 添加新的带空格的属性console.log(user.country);       // 输出: USA
console.log(user['phone number']); // 输出: 123-456-7890

3. 删除属性:
使用 delete​ 运算符可以从对象中删除一个属性。

delete user.hobbies; // 删除 hobbies 属性
console.log(user.hobbies); // 输出: undefineddelete user['e-mail']; // 删除 'e-mail' 属性
console.log(user['e-mail']); // 输出: undefined

​delete​ 操作成功会返回 true​(即使属性原本就不存在也返回 true​)。

四、当属性是函数时:方法 (Methods)

对象的属性值不仅可以是数据,还可以是函数!当一个对象的属性值是函数时,我们通常称这个属性为该对象的方法 (Method)。方法定义了对象的“行为”。

let calculator = {operand1: 0,operand2: 0,// 定义一个 add 方法add: function() {// 在方法内部,`this` 通常指向调用该方法的对象本身return this.operand1 + this.operand2;},// 使用 ES6 简洁语法定义 subtract 方法subtract() {return this.operand1 - this.operand2;},// 箭头函数作为方法(注意 this 的区别,后面详述)// multiply: () => { /* ... this behaves differently here ... */ }
};// 设置操作数
calculator.operand1 = 10;
calculator.operand2 = 5;// 调用方法,就像访问属性一样,但后面要加圆括号 ()
let sumResult = calculator.add();
console.log("Sum:", sumResult); // 输出: Sum: 15let diffResult = calculator.subtract();
console.log("Difference:", diffResult); // 输出: Difference: 5
  • 调用方法: 使用点符号或方括号访问到函数属性后,加上圆括号 ()​ 来执行它。
  • ​this​ 关键字初探: 在普通函数(非箭头函数)作为方法被调用时,函数内部的 this​ 关键字通常会指向调用该方法的那个对象(在上面的例子中,this​ 指向 calculator​ 对象)。这使得方法可以访问和操作对象自身的其他属性。关于 this​ 的复杂性,我们后续会有专门的篇章深入探讨。

五、遍历对象属性:查看“档案袋”里的所有条目

有时候,你需要知道一个对象里到底有哪些属性,或者需要依次处理每个属性。

1. for...in​ 循环:
这是专门用来遍历对象可枚举属性 (enumerable properties) 的键 (key) 的循环。

let carInfo = {make: "Honda",model: "Civic",year: 2020,color: "blue"
};for (let key in carInfo) {// key 变量在每次迭代中会是对象的一个属性名 (字符串)console.log(`Property: ${key}, Value: ${carInfo[key]}`);// 注意:这里必须用方括号 carInfo[key] 来访问属性值,// 因为 key 是一个包含属性名的字符串变量,不能用点符号 carInfo.key
}
/* 输出:
Property: make, Value: Honda
Property: model, Value: Civic
Property: year, Value: 2020
Property: color, Value: blue
*/
  • 注意: for...in​ 不仅会遍历对象自身的属性,还可能遍历到其原型链上继承来的可枚举属性(后续讲原型时会细说)。如果你只想遍历对象自身的属性,通常需要配合 hasOwnProperty()​ 方法检查。

2. Object.keys()​, Object.values()​, Object.entries()​ (ES6+)
这些是更现代、更推荐的方法,它们只关注对象自身的可枚举属性,并返回数组,可以方便地配合数组方法(如 forEach​)或 for...of​ 循环使用。

  • ​Object.keys(obj)​: 返回一个包含对象所有自身可枚举属性键名的数组。
  • ​Object.values(obj)​: 返回一个包含对象所有自身可枚举属性值的数组。
  • ​Object.entries(obj)​: 返回一个包含对象所有自身可枚举属性 [key, value]​ 对的数组。
let fruitBasket = {apple: 5,banana: 3,orange: 8
};let keys = Object.keys(fruitBasket);
console.log(keys); // 输出: ["apple", "banana", "orange"]let values = Object.values(fruitBasket);
console.log(values); // 输出: [5, 3, 8]let entries = Object.entries(fruitBasket);
console.log(entries); // 输出: [ ["apple", 5], ["banana", 3], ["orange", 8] ]// 使用 for...of 遍历 entries
console.log("--- Using Object.entries with for...of ---");
for (let [key, value] of Object.entries(fruitBasket)) {console.log(`${key}: ${value}`);
}
/* 输出:
apple: 5
banana: 3
orange: 8
*/

通常推荐使用 Object.keys/values/entries​ 结合数组方法或 for...of​ 来遍历对象属性,因为它们更可控、更清晰。

六、对象是“引用类型”

回顾一下,我们之前接触的基本数据类型(String, Number, Boolean, Null, Undefined, Symbol, BigInt)都是原始类型 (Primitive Types)。当你把一个原始类型的值赋给另一个变量时,是复制了这个值。

let x = 10;
let y = x; // y 得到的是 x 的值的副本 (10)
y = 20;   // 修改 y 不会影响 x
console.log(x); // 输出: 10

而对象 (以及数组和函数) 属于引用类型 (Reference Types)。当你把一个对象赋给另一个变量时,你复制的不是对象本身,而是指向该对象的内存地址(引用)。这意味着这两个变量实际上指向同一个对象。

let obj1 = { value: 10 };
let obj2 = obj1; // obj2 得到的是 obj1 的引用 (指向同一个对象)obj2.value = 20; // 通过 obj2 修改对象
console.log(obj1.value); // 输出: 20 (obj1 也被影响了,因为它们指向同一个对象!)obj1.newValue = 30; // 通过 obj1 添加属性
console.log(obj2.newValue); // 输出: 30 (obj2 也能看到这个新属性)

理解引用类型非常重要,尤其是在函数参数传递、对象比较等方面,它会影响代码的行为。

相关文章:

  • uniappx 打包配置32位64位x86安装包
  • UML 活动图深度解析:以在线购物系统为例
  • 游戏开发核心技术全景解析——从引擎架构到网络安全防护体系
  • LeetCode每日一题4.24
  • 微高压氧舱VS高压氧舱:氧气疗法的“双生花”如何重塑健康?
  • 数据逆序隐写
  • 考研英一学习笔记
  • 倚光科技:详解非球面光学元件的加工与检测方法
  • Python并行计算:1.Python多线程编程详解:核心概念、切换流程、GIL锁机制与生产者-消费者模型
  • 探索 CameraCtrl模型:视频生成中的精确摄像机控制技术
  • XS5032芯片,开启视觉新体验
  • 什么是机器视觉3D碰撞检测?机器视觉3D碰撞检测是机器视觉3D智能系统中安全运行的核心技术之一
  • 题目:这不是字符串题
  • UML 活动图详解:以机票预订系统用户注册为例
  • 3dmax模型怎么处理3dtiles,制作制作B3DM格式文件
  • Linux操作系统--基础I/O(上)
  • 如何获取静态IP地址?完整教程
  • 第15章:MCP服务端项目开发实战:性能优化
  • 蓝桥杯 1. 四平方和
  • 深入详解人工智能数学基础——概率论中的贝叶斯深度学习
  • 人大法工委:涉核领域还需要有一部统领性的基础法律
  • 人民论坛:是民生小事,也是融合大势
  • 牛市早报|商务部:目前中美之间未进行任何经贸谈判
  • 安徽铁塔回应“指挥调度中心大屏现不雅视频”:将严肃处理
  • 海关总署牵头部署开展跨境贸易便利化专项行动
  • 解放日报:上海一季度GDP同比增长5.1%,两大新动能助推经济“开门红”