JavaScript ES5 对象全解析
在 JavaScript ES5 中,对象是 “无序属性的集合”,其属性可包含基本值、对象或函数,是实现数据封装、逻辑复用与状态管理的核心载体。从对象创建、属性操作、类型转换、属性检测、原型特性、高级属性定义、对象序列化七个维度,深入拆解 ES5 对象的核心特性,配套文件相关案例改编的代码实例与运行结果,完整还原文件中的语法规则与最佳实践。
一、对象的创建方式
明确对象初始化有字面量模式和构造函数模式两种核心方式,二者适用场景不同,需根据对象复杂度与创建数量选择。
1.1 字面量模式(推荐用于简单对象)
通过 {} 直接包裹键值对创建对象,是 ES5 中最简洁直观的方式。文件中强调:
- 属性名默认可省略引号,若包含特殊字符(如
-、空格)则必须加引号; - 属性值支持任意数据类型(基本值、函数、其他对象、数组等);
- 方法定义可简写为
方法名: function() {},this指向当前对象。
代码实例(文件案例改编)
javascript
// 1. 基础属性+方法的对象字面量
var person = {
name: "张三",
"user-age": 22, // 含特殊字符,需加引号
gender: "male",
hobbies: ["篮球", "编程"], // 属性值为数组
address: { // 属性值为嵌套对象
province: "广东",
city: "深圳"
},
// 方法:this 指向 person 对象
sayInfo: function() {
console.log("姓名:" + this.name + ",年龄:" + this["user-age"]);
console.log("爱好:" + this.hobbies[0] + "、" + this.hobbies[1]);
}
};
// 调用方法与访问属性
person.sayInfo();
console.log("所在城市:" + person.address.city);
运行结果
姓名:张三,年龄:22
爱好:篮球、编程
所在城市:深圳
1.2 构造函数模式(推荐用于批量创建)
通过 new 关键字调用构造函数创建对象,文件中分为 “内置构造函数” 和 “自定义构造函数” 两种:
- 内置构造函数:
new Object()创建空对象,再手动添加属性 / 方法; - 自定义构造函数:通过
function定义构造函数,统一对象结构,支持批量创建同类型对象。
文件中特别提醒:构造函数名建议首字母大写,与普通函数区分;内部通过 this 绑定属性 / 方法,实例化时自动指向新对象。
代码实例
javascript
// 1. 内置 Object 构造函数
var car = new Object();
// 动态添加属性(支持后续扩展)
car.brand = "宝马";
car.model = "325Li";
car.price = 350000;
// 动态添加方法
car.showPrice = function() {
console.log(this.brand + this.model + " 价格:" + this.price + "元");
};
// 2. 自定义构造函数(批量创建学生对象)
function Student(name, score, grade) {
// 实例属性:每个实例独有的属性
this.name = name;
this.score = score;
this.grade = grade;
// 实例方法:每个实例都会创建新的函数对象(后续可通过原型优化)
this.showScore = function() {
console.log(this.name + "(" + this.grade + ")成绩:" + this.score);
};
}
// 批量创建实例
var stu1 = new Student("李四", 92, "高一(1)班");
var stu2 = new Student("王五", 85, "高一(2)班");
// 调用方法
car.showPrice();
stu1.showScore();
stu2.showScore();
运行结果
宝马325Li 价格:350000元
李四(高一(1)班)成绩:92
王五(高一(2)班)成绩:85
二、对象属性的访问与遍历
对象属性的 “访问方式” 与 “遍历规则”,是操作对象数据的基础。
2.1 属性访问:点访问 vs 中括号访问
文件中明确两种访问方式的差异与适用场景:
| 访问方式 | 语法 | 适用场景 | 限制条件 |
|---|---|---|---|
| 点访问 | obj.属性名 |
属性名是合法标识符(无特殊字符、非关键字) | 无法动态拼接属性名,属性名需提前确定 |
| 中括号访问 | obj["属性名"] |
含特殊字符的属性名、动态属性名(变量拼接) | 属性名需用字符串包裹,支持变量动态解析 |
代码实例
javascript
var product = {
"product-name": "笔记本电脑",
price: 6999,
stock: 50
};
// 1. 点访问:适用于常规属性名
console.log("价格(点访问):" + product.price); // 6999
// 2. 中括号访问:适用于特殊字符属性名
console.log("商品名(中括号访问):" + product["product-name"]); // 笔记本电脑
// 3. 动态属性名(中括号访问支持变量解析)
var prop = "stock";
console.log("库存(动态属性名):" + product[prop]); // 50
// 4. 动态拼接属性名
var propPrefix = "product";
console.log("商品名(拼接属性名):" + product[propPrefix + "-name"]); // 笔记本电脑
运行结果
价格(点访问):6999
商品名(中括号访问):笔记本电脑
库存(动态属性名):50
商品名(拼接属性名):笔记本电脑
2.2 属性遍历:for...in 循环
文件中指出 for...in 是 ES5 中唯一用于遍历对象属性的循环方式,其核心规则:
- 遍历范围:对象的可枚举属性(包括自有属性和继承属性,如
toString); - 循环变量:每次迭代获取 “属性名”(字符串类型),需通过
obj[属性名]访问属性值; - 过滤继承属性:需结合
hasOwnProperty()方法,避免遍历到原型链上的继承属性。
代码实例
javascript
var phone = {
brand: "苹果",
model: "iPhone 14",
price: 5999
};
// 1. 遍历所有可枚举属性(含继承属性)
console.log("遍历所有可枚举属性:");
for (var key in phone) {
console.log(key + ":" + phone[key]);
}
// 2. 仅遍历自有属性(文件推荐写法)
console.log("\n仅遍历自有属性:");
for (var key in phone) {
// hasOwnProperty() 检测属性是否为对象自身拥有
if (phone.hasOwnProperty(key)) {
console.log(key + ":" + phone[key]);
}
}
// 3. 遍历属性并筛选类型(如仅数值类型属性)
console.log("\n仅遍历数值类型的自有属性:");
for (var key in phone) {
if (phone.hasOwnProperty(key) && typeof phone[key] === "number") {
console.log(key + ":" + phone[key]);
}
}
运行结果
遍历所有可枚举属性:
brand:苹果
model:iPhone 14
price:5999
toString:function toString() { [native code] } // 继承属性
仅遍历自有属性:
brand:苹果
model:iPhone 14
price:5999
仅遍历数值类型的自有属性:
price:5999
三、对象属性的新增与删除
ES5 对象支持 “动态扩展”,属性的新增与删除无需提前声明,操作灵活。
3.1 新增属性
文件中说明:直接通过 “点访问” 或 “中括号访问” 赋值即可新增属性,无论对象是否已存在该属性。新增规则:
- 若属性不存在:直接添加到对象中,默认特性为
configurable: true(可删除)、enumerable: true(可遍历)、writable: true(可修改); - 若属性已存在:覆盖原有属性值,不改变属性特性。
代码实例
javascript
var book = {
title: "JavaScript 高级程序设计",
author: "尼古拉斯·泽卡斯"
};
// 1. 新增基本属性
book.publishYear = 2012; // 点访问新增
book["page-count"] = 460; // 中括号访问新增
// 2. 新增方法
book.showDetail = function() {
console.log("书名:" + this.title);
console.log("作者:" + this.author + ",页数:" + this["page-count"]);
};
// 3. 新增嵌套对象属性
book.publisher = {
name: "人民邮电出版社",
location: "北京"
};
// 调用方法与访问新增属性
book.showDetail();
console.log("出版社:" + book.publisher.name);
运行结果
书名:JavaScript 高级程序设计
作者:尼古拉斯·泽卡斯,页数:460
出版社:人民邮电出版社
3.2 删除属性
仅能通过 delete 运算符删除对象的自有属性,无法删除继承属性或不可配置属性(后续 “高级属性定义” 会详细说明)。删除规则:
- 语法:
delete obj.属性名或delete obj["属性名"]; - 返回值:删除成功(或删除不存在的属性 / 继承属性)返回
true,删除不可配置属性返回false; - 注意:删除属性后,属性彻底从对象中移除,访问该属性会返回
undefined(区别于 “属性值设为 undefined”)。
代码实例
javascript
var fruit = {
name: "苹果",
color: "红色",
price: 5,
stock: 100
};
// 1. 删除自有属性 price
var deletePrice = delete fruit.price;
console.log("删除 price 结果:" + deletePrice); // true
console.log("删除后 price:" + fruit.price); // undefined(属性已移除)
// 2. 尝试删除不存在的属性(无报错,返回 true)
var deleteWeight = delete fruit.weight;
console.log("删除不存在的 weight 结果:" + deleteWeight); // true
// 3. 尝试删除继承属性 toString(无法删除,返回 true)
var deleteToString = delete fruit.toString;
console.log("删除继承属性 toString 结果:" + deleteToString); // true
console.log("toString 是否存在:" + (fruit.toString !== undefined)); // true(仍可调用)
// 4. 删除不可配置属性(后续通过 Object.defineProperty 定义)
Object.defineProperty(fruit, "name", {
configurable: false // 设为不可配置
});
var deleteName = delete fruit.name;
console.log("删除不可配置属性 name 结果:" + deleteName); // false
运行结果
删除 price 结果:true
删除后 price:undefined
删除不存在的 weight 结果:true
删除继承属性 toString 结果:true
toString 是否存在:true
删除不可配置属性 name 结果:false
四、对象的显示类型转换
对象向布尔、字符串、数字三种基本类型的转换规则,核心依赖 toString() 和 valueOf() 方法的优先级调用。
4.1 转换为布尔类型(Boolean ())
文件中规则:除 null(空引用)外,所有对象转换为布尔值均为 true,包括空对象 {}、空数组 []、包装对象(如 new String(""))。
代码实例
javascript
var emptyObj = {}; // 空对象
var nullObj = null; // 空引用
var emptyArr = []; // 空数组
var zeroObj = new Number(0); // 数字包装对象(值为0)
console.log("空对象转布尔:" + Boolean(emptyObj)); // true
console.log("null 转布尔:" + Boolean(nullObj)); // false
console.log("空数组转布尔:" + Boolean(emptyArr)); // true
console.log("值为0的包装对象转布尔:" + Boolean(zeroObj)); // true
运行结果
空对象转布尔:true
null 转布尔:false
空数组转布尔:true
值为0的包装对象转布尔:true
4.2 转换为字符串类型(String ())
转换优先级:先调用 toString() 方法,再调用 valueOf() 方法,具体步骤:
- 调用对象的
toString()方法,若返回 “基本数据类型”(String/Number/Boolean/Null/Undefined),则按该类型的转换规则转为字符串; - 若
toString()返回 “引用类型”(如对象、数组),则调用valueOf()方法; - 若
valueOf()返回基本数据类型,转为字符串;若仍为引用类型,则抛出类型错误。
特别说明:Date 对象是例外,其 toString() 优先级高于 valueOf(),直接返回格式化的日期字符串。
代码实例
javascript
// 1. 普通对象(重写 toString() 自定义转换)
var person = {
name: "张三",
age: 22,
// 重写 toString(),返回基本类型(字符串)
toString: function() {
return this.name + "-" + this.age;
},
// valueOf() 仅在 toString() 返回引用类型时生效
valueOf: function() {
return this.age;
}
};
// 2. 数组对象(默认 toString() 转为逗号分隔字符串)
var arr = [1, 2, 3, "a"];
// 3. Date 对象(优先调用 toString())
var now = new Date();
console.log("普通对象转字符串:" + String(person)); // 张三-22(调用 toString())
console.log("数组转字符串:" + String(arr)); // 1,2,3,a(调用默认 toString())
console.log("Date 对象转字符串:" + String(now)); // 如:Mon Aug 23 2021 15:30:00 GMT+0800 (中国标准时间)
运行结果
普通对象转字符串:张三-22
数组转字符串:1,2,3,a
Date 对象转字符串:Mon Aug 23 2021 15:30:00 GMT+0800 (中国标准时间)
4.3 转换为数字类型(Number ())
明确转换优先级与字符串转换相反:先调用 valueOf() 方法,再调用 toString() 方法,具体步骤:
- 调用对象的
valueOf()方法,若返回基本数据类型,按该类型的转换规则转为数字; - 若
valueOf()返回引用类型,则调用toString()方法; - 若
toString()返回基本数据类型,转为数字;若仍为引用类型,则抛出类型错误。
特别说明:若同时重写 valueOf() 和 toString(),优先使用 valueOf() 的返回值。
代码实例
javascript
// 1. 普通对象(重写 valueOf() 和 toString())
var numObj = {
value: 10,
// 重写 valueOf(),返回基本类型(数字)
valueOf: function() {
return this.value;
},
// 仅当 valueOf() 返回引用类型时,toString() 才生效
toString: function() {
return this.value + 5;
}
};
// 2. 数组对象(valueOf() 返回数组本身,需调用 toString())
var arr1 = [10]; // toString() 转为 "10"
var arr2 = [10, 20]; // toString() 转为 "10,20"(非纯数字字符串,转数字为 NaN)
console.log("普通对象转数字:" + Number(numObj)); // 10(调用 valueOf())
console.log("数组 [10] 转数字:" + Number(arr1)); // 10(valueOf() 返回数组,调用 toString() 转为 "10")
console.log("数组 [10,20] 转数字:" + Number(arr2)); // NaN(toString() 转为 "10,20",非纯数字)
console.log("对象参与加法运算:" + (numObj + 5)); // 15(隐式转数字,调用 valueOf())
运行结果
普通对象转数字:10
数组 [10] 转数字:10
数组 [10,20] 转数字:NaN
对象参与加法运算:15
五、对象属性的检测
提供三种核心方式检测属性与对象的关系,分别对应不同的检测范围,需根据需求选择。
| 检测方式 | 检测范围 | 核心作用 | 返回值 |
|---|---|---|---|
key in obj |
自有属性 + 继承属性 | 检测属性是否存在于对象或其原型链上 | 布尔值 |
obj.hasOwnProperty(key) |
仅自有属性 | 区分属性是 “对象自身拥有” 还是 “原型继承” | 布尔值 |
obj.propertyIsEnumerable(key) |
仅 “可枚举的自有属性” | 检测自有属性是否可通过 for...in 遍历 |
布尔值 |
文件中强调:for...in 循环仅遍历 “可枚举属性”,而 hasOwnProperty() 与 propertyIsEnumerable() 是过滤继承属性、控制遍历范围的关键工具。
代码实例
javascript
var obj = {
name: "张三",
age: 22
};
// 1. in 运算符:检测自有属性和继承属性
console.log("name in obj:" + ("name" in obj)); // true(自有属性)
console.log("toString in obj:" + ("toString" in obj)); // true(继承属性,来自 Object.prototype)
console.log("gender in obj:" + ("gender" in obj)); // false(不存在)
// 2. hasOwnProperty():仅检测自有属性
console.log("\nobj.hasOwnProperty('name'):" + obj.hasOwnProperty("name")); // true
console.log("obj.hasOwnProperty('toString'):" + obj.hasOwnProperty("toString")); // false(继承属性)
console.log("obj.hasOwnProperty('gender'):" + obj.hasOwnProperty("gender")); // false(不存在)
// 3. propertyIsEnumerable():检测“可枚举的自有属性”
console.log("\nobj.propertyIsEnumerable('name'):" + obj.propertyIsEnumerable("name")); // true(可枚举)
console.log("obj.propertyIsEnumerable('toString'):" + obj.propertyIsEnumerable("toString")); // false(继承属性)
// 4. 不可枚举的自有属性(通过 Object.defineProperty 定义)
Object.defineProperty(obj, "id", {
value: 1001,
enumerable: false // 设为不可枚举
});
console.log("obj.hasOwnProperty('id'):" + obj.hasOwnProperty("id")); // true(自有属性)
console.log("obj.propertyIsEnumerable('id'):" + obj.propertyIsEnumerable("id")); // false(不可枚举)
console.log("id in obj:" + ("id" in obj)); // true(存在)
运行结果
name in obj:true
toString in obj:true
gender in obj:false
obj.hasOwnProperty('name'):true
obj.hasOwnProperty('toString'):false
obj.hasOwnProperty('gender'):false
obj.propertyIsEnumerable('name'):true
obj.propertyIsEnumerable('toString'):false
obj.hasOwnProperty('id'):true
obj.propertyIsEnumerable('id'):false
id in obj:true
六、深入理解对象:数据属性与访问器属性
对象属性分为数据属性(存储具体值)和访问器属性(通过 getter/setter 控制访问逻辑),二者均需通过 Object.defineProperty() 或 Object.defineProperties() 定义 / 修改,是实现属性权限控制、数据拦截的核心特性。
6.1 数据属性:控制值的存储与访问权限
数据属性用于存储具体值,包含四个不可直接访问的内部特性(用 [[ ]] 表示),文件中定义:
| 内部特性 | 含义 | 默认值(直接定义的属性) |
|---|---|---|
[[Configurable]] |
能否通过 delete 删除属性、修改特性、转为访问器属性 |
true |
[[Enumerable]] |
能否通过 for...in 遍历属性 |
true |
[[Writable]] |
能否修改属性值 | true |
[[Value]] |
存储属性的实际值,访问属性时读取,修改属性时更新 | undefined |
强调:直接通过 obj.属性 = 值 定义的属性,默认特性均为 true;若需修改特性,必须使用 Object.defineProperty()。
代码实例
javascript
var person = {};
// 1. 定义数据属性:不可删除、不可枚举、可写
Object.defineProperty(person, "name", {
configurable: false, // 不可删除、不可修改特性
enumerable: false, // 不可通过 for...in 遍历
writable: true, // 可修改属性值
value: "张三" // 初始值
});
// 2. 定义多个数据属性(Object.defineProperties)
Object.defineProperties(person, {
age: {
configurable: true,
enumerable: true,
writable: false, // 不可修改
value: 22
},
gender: {
configurable: true,
enumerable: true,
writable: true,
value: "male"
}
});
// 测试特性
console.log("初始 name:" + person.name); // 张三
console.log("初始 age:" + person.age); // 22
// 修改可写属性(name 可写,age 不可写)
person.name = "李四";
person.age = 23; // 不可写,修改无效
console.log("修改后 name:" + person.name); // 李四
console.log("修改后 age:" + person.age); // 22
// 尝试删除不可配置属性(name 不可删除)
var deleteName = delete person.name;
console.log("删除 name 结果:" + deleteName); // false
// 遍历属性(name 不可枚举,仅显示 age、gender)
console.log("\n遍历可枚举属性:");
for (var key in person) {
console.log(key + ":" + person[key]);
}
运行结果
初始 name:张三
初始 age:22
修改后 name:李四
修改后 age:22
删除 name 结果:false
遍历可枚举属性:
age:22
gender:male
6.2 访问器属性:实现数据拦截与逻辑封装
访问器属性不直接存储值,而是通过 get(读取时触发)和 set(修改时触发)方法控制访问逻辑,文件中定义其内部特性:
| 内部特性 | 含义 | 默认值 |
|---|---|---|
[[Configurable]] |
能否通过 delete 删除属性、修改特性、转为数据属性 |
false |
[[Enumerable]] |
能否通过 for...in 遍历属性 |
false |
[[Get]] |
读取属性时调用的函数,返回属性值,默认 undefined |
undefined |
[[Set]] |
修改属性时调用的函数,接收新值,默认 undefined |
undefined |
文件中特别说明:访问器属性不能直接定义,必须通过 Object.defineProperty();若仅定义 get 无 set,则属性为 “只读”。
代码实例(模拟数据双向绑定)
javascript
var book = {
_year: 2020, // 下划线约定为“私有属性”,不建议外部直接访问
editor: 1 // 编辑器版本,year 修改时自动递增
};
// 定义访问器属性 year
Object.defineProperty(book, "year", {
// get 方法:读取 year 时触发,返回 _year 的值
get: function() {
console.log("读取 year 属性");
return this._year;
},
// set 方法:修改 year 时触发,接收新值 newYear
set: function(newYear) {
console.log("修改 year 属性:" + newYear);
if (newYear !== this._year) { // 仅当新值与旧值不同时更新
this._year = newYear;
this.editor++; // 自动递增编辑器版本
}
},
configurable: true,
enumerable: true
});
// 访问访问器属性
console.log("初始 year:" + book.year); // 触发 get,输出 2020
console.log("初始 editor:" + book.editor); // 1
// 修改访问器属性(触发 set)
book.year = 2023;
console.log("修改后 year:" + book.year); // 触发 get,输出 2023
console.log("修改后 editor:" + book.editor); // 2
// 尝试修改为相同值(set 中判断,不更新)
book.year = 2023;
console.log("重复修改后 editor:" + book.editor); // 仍为 2
运行结果
读取 year 属性
初始 year:2020
初始 editor:1
修改 year 属性:2023
读取 year 属性
修改后 year:2023
修改后 editor:2
修改 year 属性:2023
重复修改后 editor:2
文件中指出:访问器属性是 Vue 等框架 “数据双向绑定” 的核心原理 —— 通过 set 方法监听数据变化,触发视图更新;通过 get 方法读取数据,实现数据响应式。
七、对象序列化与反序列化
对象序列化是将对象状态转换为可传输 / 存储的字符串,反序列化则是将字符串还原为对象。ES5 中通过 JSON.stringify()(序列化)和 JSON.parse()(反序列化)实现,核心规则:
- 可序列化类型:对象的 “可枚举自有属性”(基本值、数组、嵌套对象);
- 不可序列化类型:
RegExp、Error对象、undefined、函数(会被忽略或转为null); - 序列化结果:JSON 格式字符串,属性名自动加双引号,函数、
undefined等会被过滤。
7.1 序列化(JSON.stringify ())
语法:JSON.stringify(obj, [replacer], [space]),可选参数:
replacer:函数或数组,用于过滤 / 转换属性(如数组仅保留指定属性,函数自定义转换逻辑);space:数字或字符串,用于格式化输出(如数字表示缩进空格数,增强可读性)。
代码实例
javascript
var user = {
name: "张三",
age: 22,
isStudent: true,
hobbies: ["篮球", "编程"],
address: {
province: "广东",
city: "深圳"
},
sayHello: function() { // 函数,不可序列化,会被过滤
console.log("Hello");
},
weight: undefined // undefined,不可序列化,会被过滤
};
// 1. 基础序列化(过滤函数、undefined)
var jsonStr1 = JSON.stringify(user);
console.log("基础序列化结果:" + jsonStr1);
// 2. 数组 replacer:仅保留 name、age、hobbies 属性
var jsonStr2 = JSON.stringify(user, ["name", "age", "hobbies"]);
console.log("\n指定属性序列化:" + jsonStr2);
// 3. 函数 replacer:自定义属性值转换(如 age 加 1)
var jsonStr3 = JSON.stringify(user, function(key, value) {
if (key === "age") {
return value + 1; // age 转为 23
}
return value;
}, 2); // 缩进 2 个空格,格式化输出
console.log("\n自定义转换并格式化:");
console.log(jsonStr3);
运行结果
基础序列化结果:{"name":"张三","age":22,"isStudent":true,"hobbies":["篮球","编程"],"address":{"province":"广东","city":"深圳"}}
指定属性序列化:{"name":"张三","age":22,"hobbies":["篮球","编程"]}
自定义转换并格式化:
{
"name": "张三",
"age": 23,
"isStudent": true,
"hobbies": [
"篮球",
"编程"
],
"address": {
"province": "广东",
"city": "深圳"
}
}
7.2 反序列化(JSON.parse ())
语法:JSON.parse(jsonStr, [reviver]),可选参数 reviver 为函数,用于还原时自定义属性值(如日期字符串转为 Date 对象)。
代码实例
javascript
// JSON 字符串(序列化结果)
var jsonStr = `{
"name": "张三",
"age": 22,
"regTime": "2021-08-23T10:00:00.000Z",
"scores": [85, 92, 78]
}`;
// 1. 基础反序列化
var user1 = JSON.parse(jsonStr);
console.log("基础反序列化结果:");
console.log(user1.name + ",年龄:" + user1.age);
console.log("regTime 类型:" + typeof user1.regTime); // string(需手动转为 Date)
// 2. reviver 函数:将 regTime 字符串转为 Date 对象
var user2 = JSON.parse(jsonStr, function(key, value) {
if (key === "regTime") {
return new Date(value); // 转为 Date 对象
}
// 处理 scores:将分数转为数组并计算平均分
if (key === "scores") {
var avg = value.reduce((sum, item) => sum + item, 0) / value.length;
value.avg = avg; // 为数组添加 avg 属性
return value;
}
return value;
});
console.log("\n自定义反序列化结果:");
console.log("regTime 类型:" + typeof user2.regTime); // object(Date 对象)
console.log("注册时间:" + user2.regTime.toLocaleString());
console.log("分数数组:" + user2.scores + ",平均分:" + user2.scores.avg);
运行结果
基础反序列化结果:
张三,年龄:22
regTime 类型:string
自定义反序列化结果:
regTime 类型:object
注册时间:2021/8/23 18:00:00
分数数组:85,92,78,平均分:85
八、总结
- 对象本质:无序属性的集合,属性可包含基本值、对象或函数,是 ES5 中数据封装与逻辑复用的核心;
- 创建方式:字面量模式适合简单对象,构造函数模式适合批量创建,需根据场景选择;
- 属性操作:支持动态增删,访问方式需结合属性名特性(点访问 / 中括号访问),遍历需过滤继承属性;
- 类型转换:布尔转换仅
null为false,字符串 / 数字转换依赖toString()/valueOf()优先级; - 高级特性:数据属性控制读写权限,访问器属性实现数据拦截,是 ES5 对象灵活性的核心;
- 序列化:
JSON.stringify()/JSON.parse()实现对象与字符串的转换,需注意不可序列化类型的过滤。
更多推荐



所有评论(0)