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

跟着 MDN 学JavaScript day_24:JavaScript对象基础完全指南

引言:为什么需要对象

在JavaScript编程的世界里,对象是最核心的概念之一。当你开始构建稍微复杂的应用程序时,很快就会意识到,使用独立分散的变量来存储相关联的数据是多么笨拙和低效。

constpersonName="张三";constpersonAge=28;constpersonOccupation="工程师";

随着应用规模的增长,这些零散的变量不仅难以管理,还容易导致命名冲突和代码混乱。如果要表示多个人,情况会变得更加糟糕。

对象应运而生,它提供了一种优雅的方式,将相关的数据和功能组织在一起,形成一个逻辑上独立的单元:

constperson={name:"张三",age:28,occupation:"工程师"};

对象反映了我们对现实世界的自然认知方式——将一个人视为具有各种属性和行为的整体,而不是孤立的特征集合。


一、对象基础:什么是对象字面量

对象本质上是一个包含相关数据和方法的集合。在对象的语境中:数据项被称为属性,函数被称为方法

创建对象最简单直接的方式是使用对象字面量语法——通过手动编写对象的内容来创建对象。

1.1 空对象

constperson={};

虽然空对象本身做不了什么,但它标志着我们开始使用一种全新的数据组织方式。

1.2 完整的对象示例

constperson={name:["Bob","Smith"],age:32,bio:function(){console.log(`${this.name[0]}${this.name[1]}现在${this.age}岁了。`);},introduceSelf:function(){console.log(`你好!我是${this.name[0]}`);},};

1.3 ES6 方法简写

当对象的成员是函数时,可以省略冒号和function关键字:

constperson={name:["Bob","Smith"],age:32,bio(){console.log(`${this.name[0]}${this.name[1]}现在${this.age}岁了。`);},introduceSelf(){console.log(`你好!我是${this.name[0]}`);},};

1.4 访问对象成员

person.name;// ["Bob", "Smith"]person.name[0];// "Bob"person.age;// 32person.bio();// "Bob Smith 现在 32 岁了。"person.introduceSelf();// "你好!我是 Bob。"

对象字面量的典型使用场景:需要传输一系列结构化的相关数据项时(如向服务器发送请求),发送一个对象比分别发送多个独立数据项更有效率。


二、点表示法:访问对象属性的主要方式

点表示法是访问对象属性和方法最常用、最直观的方式。对象名充当命名空间的角色,为内部成员提供上下文:

person.age;// 访问属性person.bio();// 调用方法

2.1 链式访问(子命名空间)

当一个对象成员本身又是一个对象时,可以继续使用点表示法深入访问:

constperson={name:{first:"Bob",last:"Smith",},age:32,bio(){console.log(`${this.name.first}${this.name.last}现在${this.age}岁了。`);},introduceSelf(){console.log(`你好!我是${this.name.first}`);},};person.name.first;// "Bob"person.name.last;// "Smith"
层级访问路径结果
第一层person整个对象
第二层person.name{first: "Bob", last: "Smith"}
第三层person.name.first"Bob"

⚠️ 修改对象的内部结构时,所有引用该结构的代码都需要同步更新。例如:数组索引 → 嵌套对象属性名。


三、括号表示法:动态访问对象属性

括号表示法作为点表示法的替代方案,语法与数组访问相似:

person["age"];person["name"]["first"];

3.1 对象本质上是关联数组

数组类型键(Key)映射
普通数组数字索引0 → "hello"
对象字符串键"name" → "Bob"

3.2 括号表示法的独特优势:动态属性名

点表示法只接受字面量成员名,而括号表示法可以接受变量作为属性名:

constperson={name:["Bob","Smith"],age:32,};functionlogProperty(propertyName){console.log(person[propertyName]);}logProperty("name");// ["Bob", "Smith"]logProperty("age");// 32
方式适用场景
点表示法person.age属性名在编写代码时已知(大多数情况)
括号表示法person["age"]属性名保存在变量中,运行时动态确定

四、设置对象成员:不仅仅是更新

通过点表示法或括号表示法,不仅可以查询对象成员的值,还可以设置或更新它们。

4.1 更新已有属性

person.age=45;person["name"]["last"]="Cratchit";

4.2 动态创建新成员

即便某个属性在对象定义时不存在,也可以在程序运行中通过赋值添加:

person["eyes"]="hazel";person.farewell=function(){console.log("再见!");};person["eyes"];// "hazel"person.farewell();// "再见!"

4.3 括号表示法动态设置成员名

属性名本身也可以是变量,在运行时才确定:

constmyDataName="height";constmyDataValue="1.75m";person[myDataName]=myDataValue;person.height;// "1.75m"

实际应用:从输入框获取属性名和属性值,动态添加到对象中:

constmyDataName=nameInput.value;constmyDataValue=nameValue.value;person[myDataName]=myDataValue;// 点表示法无法实现!

五、"this"关键字:上下文引用的奥秘

在对象的方法定义中,this指向当前代码运行时所在的对象——即调用该方法的对象实例。

constperson={name:["Bob","Smith"],introduceSelf(){console.log(`你好!我是${this.name[0]}`);},};

5.1 this 的核心价值:代码复用

当只有一个对象时,this和直接使用对象名没有实质区别。但当存在多个对象时,this的优势就凸显出来:

constperson1={name:"Chris",introduceSelf(){console.log(`你好!我是${this.name}`);},};constperson2={name:"Deepti",introduceSelf(){console.log(`你好!我是${this.name}`);},};person1.introduceSelf();// "你好!我是 Chris。"person2.introduceSelf();// "你好!我是 Deepti。"
使用对象名引用(❌ 不灵活): person1.introduceSelf() → console.log(`你好!我是 ${person1.name}。`) person2.introduceSelf() → console.log(`你好!我是 ${person2.name}。`) → 方法定义不同,无法复用 使用 this 引用(✅ 灵活): person1.introduceSelf() → this = person1 → this.name = "Chris" person2.introduceSelf() → this = person2 → this.name = "Deepti" → 方法定义完全相同,this 自动适配调用者

this让同样的方法代码对不同对象产生不同输出,实现了代码复用和行为的多态


六、构造函数:批量创建对象的工厂

6.1 对象字面量的局限

当需要创建多个结构相同的对象时,对象字面量需要重复编写大量相同代码:

// 重复劳动,低效且容易出错constsalva={name:"Salva",introduceSelf(){...}};constfrankie={name:"Frankie",introduceSelf(){...}};constchris={name:"Chris",introduceSelf(){...}};

6.2 工厂函数(过渡方案)

functioncreatePerson(name){constobj={};obj.name=name;obj.introduceSelf=function(){console.log(`你好!我是${this.name}`);};returnobj;}constsalva=createPerson("Salva");constfrankie=createPerson("Frankie");salva.introduceSelf();// "你好!我是 Salva。"frankie.introduceSelf();// "你好!我是 Frankie。"

6.3 构造函数(标准做法)

构造函数与普通函数的区别在于使用new关键字调用。按照惯例,构造函数以大写字母开头

functionPerson(name){this.name=name;this.introduceSelf=function(){console.log(`你好!我是${this.name}`);};}// 使用 new 关键字调用constsalva=newPerson("Salva");constfrankie=newPerson("Frankie");salva.introduceSelf();// "你好!我是 Salva。"frankie.introduceSelf();// "你好!我是 Frankie。"

6.4 new 关键字自动完成的四个步骤

① 创建一个空对象 → {} ② 将 this 绑定到新对象 → this = {} ③ 运行构造函数中的代码 → this.name = "Salva"; ... ④ 返回新对象 → return this(自动完成)

6.5 三种创建方式对比

方式语法适用场景代码复用
对象字面量const obj = { ... }单个对象、传输数据❌ 无法复用
工厂函数function create() { return {...} }少量相似对象⚠️ 较冗长
构造函数new Person()批量创建同类型对象✅ 标准做法

七、你一直在使用对象:无处不在的内置对象

回顾之前学过的JavaScript知识,许多熟悉的功能实际上都是通过对象来实现的。

7.1 String 对象

constmyString="Hello,World";myString.split(",");// ["Hello", "World"]

每次创建字符串时,该字符串都会被自动创建为String的实例,因此可以访问原型上的split()toUpperCase()trim()等方法。

7.2 Document 对象(DOM)

constmyDiv=document.createElement("div");constmyVideo=document.querySelector("video");

页面加载完毕后,Document的实例document被创建,代表整个页面的结构、内容和功能。

7.3 Array 对象

constarr=[1,2,3];arr.push(4);// Array 实例的方法arr.map(x=>x*2);// 同上

7.4 Math 对象

Math.PI;// 3.14159...(静态属性)Math.random();// 随机数(静态方法)

Math是内置对象,不需要实例化即可直接使用。

7.5 需要手动实例化的 API

constmyNotification=newNotification("你好!");

不同API的设计思想不同,但底层原理相通:它们都是基于JavaScript的对象系统构建的。


总结

知识点核心内容
对象字面量{ key: value }创建单个对象,适合传输结构化数据
点表示法person.age,属性名已知时使用
括号表示法person["age"],属性名为变量时使用
动态设置成员person[varName] = value,属性名运行时确定
this关键字指向调用方法的对象实例,实现代码复用和多态
构造函数new Person()批量创建同类型对象
内置对象StringArrayDocumentMath等都是对象

对象的核心价值:将相关的属性和方法封装在一起,形成逻辑上独立的单元。对象使我们将信息安全地锁在它们自己的包内,防止命名冲突和数据混乱。

在掌握了对象基础之后,下一步将探索JavaScript更具特色的概念——原型。原型是JavaScript实现对象继承的基本方式,让对象能够从其他对象继承属性和方法,进一步扩展代码复用的可能性。


还在为 JavaScript 代码写得像“意大利面条”、逻辑混乱难以维护而头秃?收藏本文持续跟进,后续将系统分享 JS 高效语法糖、浏览器兼容与 Polyfill 实战、手写核心源码解析、常见坑点避雷指南,从基础语法到进阶逻辑一站式打通,助你快速提升前端开发硬实力!

http://www.cnnetsun.cn/news/2898754.html

相关文章:

  • 2026年AI智能体必学!小白程序员掌握Agent开发,拓宽求职赛道,高薪就业不是梦!收藏这份学习路线!
  • 【趣解】μC/OS:教学和工业双修的实时操作系统
  • 你以为抓到了 Alpha,其实抓到的是 Beta——板块归因模块完整解剖
  • 潜在扩散模型在医学图像生成中的应用与技术解析
  • 电热毛巾架哪个品牌靠谱
  • 泉州思维博清洁设备夯实闽南厂区环卫清洁设备供应实力
  • 用Arduino UNO R3玩转RGB三色灯:从流水灯到呼吸灯的保姆级代码详解
  • VidDown 工具站:免费、本地优先的开发者工具箱
  • 盘点2026年主流自动化测试工具:覆盖全场景核心功能
  • 告别理论推导!用Mathcad和SIMPLIS手把手搞定峰值电流模式Buck环路补偿
  • PostgreSQL 配置避坑指南:Flink CDC 实时同步前的 5 个关键检查点
  • 计算机Java毕设实战-基于 SpringBoot + 数据可视化的小区物业综合管理系统的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 告别手写体识别烦恼:用PyTorch复现CRNN,从论文到代码的保姆级实践
  • ROS Noetic下,手把手教你为URDF机器人模型添加深度摄像头(Gazebo仿真)
  • PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等数据库
  • 5分钟快速上手:Locale-Emulator终极指南,彻底解决日文游戏乱码问题
  • Claude Code (Linux/WSL2) 安装+api配置手把手指南
  • Plain Craft Launcher 2:快速上手指南与完整功能解析
  • 航司采购需求解析LLM调优:基于2026年大模型后训练范式的深度实践
  • 别再只用Web界面了!Proxmox VE 8.x 命令行高手必备的 qm 命令实战手册
  • EduCoder学习效率提升指南:除了找答案,这些隐藏功能和正确使用姿势你知道吗?
  • 保姆级教程:从零集成华为ScanKit到你的Android项目(含权限、依赖、回调全流程)
  • 《Go 数据库编程开篇:彻底打通 database/sql 与 MySQL 驱动的连接池调优密码》
  • CH32V307 SPI实战:手把手教你用逻辑分析仪调试SPI时序(附波形图)
  • C语言基础语法,分支语句
  • 终极B站视频下载方案:一键解锁4K高清会员内容
  • 别再手动做报表了!用永洪BI Desktop,5分钟搞定一份动态销售仪表板(附详细步骤)
  • 别再手动签名了!用Zephyr的MCUBoot实现固件安全升级,这篇保姆级教程带你搞定RSA-2048签名和分区配置
  • 企业级SSD好在哪?是否耐用——常见问题全解答
  • wxPython Phoenix:Python 跨平台 GUI 的延续