object 也就是对象,是编程里面非常核心的数据类型,在 JavaScript 里面 object 属于引用类型,简单理解它就是一个可以存放多组键值对的容器,不像数字字符串布尔值这种基础类型只能存单个值,object 可以把相关联的数据和功能打包在一起,里面既可以存属性也就是数据,也可以存方法也就是函数,很多初学者容易把 object 单纯理解成字典或者键值表,其实它还具备原型链动态增删属性引用传递这些高级特性,和基础类型的存储方式完全不一样,基础类型是值拷贝,object 是引用拷贝,这个特点也是开发里面最容易踩坑的地方,日常写代码无论是接口返回数据配置项业务实体,大量场景都会用到 object,学习 object 不能只停留在创建和读取,还要掌握遍历删除原型拷贝判断类型这些操作,理解引用类型底层逻辑,才能避开赋值比较深拷贝浅拷贝这类经典 bug。
一、object 基础定义
object 中文一般称作对象,本质是无序键值对集合,键名称也叫属性名,一般是字符串或者 Symbol,属性值可以是任意类型,数字字符串布尔值数组甚至另外一个 object 或者函数都可以,如果属性值是函数,这个属性就称作对象的方法。
基础类型和 object 核心区别
基础类型 number string boolean null undefined bigint symbol 存储的是值本身
object 存储的是内存地址,变量保存的不是完整对象内容,只是指向内存的引用地址
二、创建 object 常用方式清单
第一种 对象字面量,开发最常用,大括号包裹键值对
第二种 new Object 构造函数创建
第三种 自定义构造函数创建,适合批量创建同结构 object
第四种 Object.create 创建,可以指定原型对象
三、object 常用操作对照表
| 操作名称 | 作用 | 说明 |
|---|---|---|
| 读取属性 | 获取 object 里面属性值 | 点语法 方括号语法 |
| 新增属性 | 给 object 添加新键值对 | object 可以动态增加属性,不需要提前声明 |
| 修改属性 | 覆盖原有属性值 | 直接重新赋值 |
| 删除属性 | 移除 object 里面属性 | delete 关键字 |
| 遍历属性 | 循环读取 object 全部键 | for in Object.keys Object.values Object.entries |
| 判断属性是否存在 | 检测 object 是否拥有该属性 | in 运算符 hasOwnProperty |
四、object 核心特性深度说明
第一 动态特性,object 创建之后随时可以增加删除修改属性,不像部分强类型语言类对象必须提前定义全部字段。
第二 引用传递,把一个 object 变量赋值给另一个变量,两个变量指向同一个内存对象,修改其中一个,另一个同步变化,这就是浅拷贝相关问题来源。
第三 原型链,每个 object 都自带原型 prototype 相关属性,可以继承原型上面的方法,比如 toString hasOwnProperty 就是原型自带方法。
第四 属性描述符,object 里面每个属性都有配置,包含是否可写是否可枚举是否可配置,可以通过 Object.defineProperty 修改这些配置。
第五 键名规则,普通键名如果不带引号,必须符合标识符规则,如果带特殊符号空格数字开头,必须使用引号包裹,读取的时候只能用方括号语法。
五、object 常见操作步骤
第一步 创建 object,优先使用字面量写法,确定需要存放的业务字段。
第二步 读写属性,静态字段使用点语法,动态变量作为键的时候使用方括号语法。
第三步 遍历 object,如果只需要键名使用 Object.keys,如果需要键值对使用 Object.entries。
第四步 区分自有属性和继承属性,for in 会遍历原型链上可枚举属性,遍历业务数据推荐搭配 hasOwnProperty 过滤。
第五步 处理拷贝需求,如果只是简单赋值会共享引用,需要独立副本就要区分浅拷贝和深拷贝,多层嵌套 object 必须深拷贝。
第六步 类型校验,typeof 判断 object 的时候会出现 null 也返回 object 这个经典坑,判断纯 object 一般结合 Object.prototype.toString.call。
六、拓展补充
在其他编程语言里面 object 概念含义会有差别,比如 Java 里面 object 是所有类的根类,但是日常前端教程里面提到 object 默认就是 JavaScript 对象,object 是 JSON 格式的底层原型,JSON 本质就是 object 的字符串序列化形式,但是 JSON 里面不能存函数 undefined 循环引用,这点和原生 JS object 不一样,循环引用是 object 特殊场景,也就是 object 里面属性又指向自身,普通 JSON 序列化会报错。
【常见问题】
问题 1 typeof 为什么判断 object 的时候 null 也返回 object
回答 1 这是 JavaScript 历史遗留设计问题,typeof 判断 object 的时候,null 底层被识别成空对象指针,所以返回 object,判断纯 object 不能只依靠 typeof,需要结合 Object.prototype.toString 来准确识别 object。
问题 2 object 赋值之后修改为什么两个变量一起变
回答 1 因为 object 属于引用类型,变量保存的是内存地址,把 object 赋值给新变量,两个变量指向同一个 object,所以修改其中一个 object,另一个变量读取到的内容同步改变。
问题 3 for in 遍历 object 会遍历原型属性吗
回答 1 for in 遍历 object 的时候,会遍历原型链上所有可枚举属性,如果只想要 object 本身自有属性,需要使用 hasOwnProperty 做过滤,避免读取到继承来的属性。
问题 4 object 和 JSON 是什么关系
回答 1 JSON 是 object 的字符串表达形式,原生 object 可以包含函数和循环引用,但是 JSON 格式的 object 不支持函数 undefined 和循环引用,序列化 object 的时候这些内容会丢失。
【免责申明】
本文内容以 JavaScript 语言环境讲解 object 概念,不同编程语言 object 定义存在差异,代码示例属于基础教学演示,实际项目请结合框架规范编写,不替代官方语言文档。


