JavaScript 对象说明
JavaScript 对象说明
1. 对象的基本概念
在 JavaScript 中,对象是一种复合数据类型,用于存储相关联的属性和方法。对象可以看作是属性的集合,其中每个属性都由一个键(key)和一个值(value)组成。值可以是任何 JavaScript 数据类型,包括数字、字符串、布尔值、数组、函数,甚至是其他对象。
JavaScript 对象具有以下特点:
- 是一种引用数据类型
- 具有动态特性,可以随时添加、修改或删除属性
- 支持原型继承
- 可以通过多种方式创建
2. 创建对象的方法
2.1 对象字面量
对象字面量是创建对象最常用和最简洁的方法,使用花括号 {}
定义。
// 空对象
const emptyObject = {};// 包含属性的对象
const person = {name: "张三",age: 30,isStudent: false,hobbies: ["阅读", "编程", "旅行"],address: {city: "北京",district: "朝阳区"},sayHello: function() {console.log(`你好,我是${this.name}!`);}
};
2.2 使用 new Object() 构造函数
const person = new Object();
person.name = "张三";
person.age = 30;
person.sayHello = function() {console.log(`你好,我是${this.name}!`);
};
2.3 使用 Object.create() 方法
Object.create()
方法创建一个新对象,使用现有的对象作为新对象的原型。
// 创建一个原型对象
const personPrototype = {sayHello: function() {console.log(`你好,我是${this.name}!`);}
};// 使用原型对象创建新对象
const person = Object.create(personPrototype);
person.name = "张三";
person.age = 30;
2.4 构造函数模式
使用构造函数可以创建多个具有相同属性和方法的对象实例。
// 定义构造函数
function Person(name, age) {this.name = name;this.age = age;this.sayHello = function() {console.log(`你好,我是${this.name}!`);};
}// 使用 new 关键字创建对象实例
const person1 = new Person("张三", 30);
const person2 = new Person("李四", 25);
2.5 原型模式
将方法定义在构造函数的原型上,可以让所有实例共享这些方法,节省内存。
// 定义构造函数
function Person(name, age) {this.name = name;this.age = age;
}// 在原型上定义方法
Person.prototype.sayHello = function() {console.log(`你好,我是${this.name}!`);
};// 创建对象实例
const person1 = new Person("张三", 30);
const person2 = new Person("李四", 25);
2.6 ES6 类语法
ES6 引入了类(class)语法,提供了更接近传统面向对象语言的语法糖,但底层仍然基于原型。
// 使用 class 定义类
class Person {constructor(name, age) {this.name = name;this.age = age;}sayHello() {console.log(`你好,我是${this.name}!`);}
}// 创建类的实例
const person = new Person("张三", 30);
3. 对象的属性操作
3.1 访问对象属性
有两种方式可以访问对象的属性:点表示法(.)和方括号表示法([])。
const person = {name: "张三",age: 30,"full-name": "张三先生"
};// 点表示法
console.log(person.name); // 输出: 张三// 方括号表示法
console.log(person["age"]); // 输出: 30
console.log(person["full-name"]); // 输出: 张三先生 (适用于包含特殊字符的属性名)// 使用变量作为属性名
const prop = "name";
console.log(person[prop]); // 输出: 张三
3.2 添加新属性
可以随时为对象添加新属性。
const person = {name: "张三",age: 30
};// 添加新属性
person.email = "zhangsan@example.com";
person["phone"] = "13800138000";console.log(person);
// 输出: { name: '张三', age: 30, email: 'zhangsan@example.com', phone: '13800138000' }
3.3 修改属性值
const person = {name: "张三",age: 30
};// 修改属性值
person.age = 31;
person["name"] = "张三丰";console.log(person);
// 输出: { name: '张三丰', age: 31 }
3.4 删除属性
使用 delete
操作符可以删除对象的属性。
const person = {name: "张三",age: 30,email: "zhangsan@example.com"
};// 删除属性
delete person.email;console.log(person);
// 输出: { name: '张三', age: 30 }
console.log(person.email); // 输出: undefined
3.5 检查属性是否存在
使用 in
操作符或 hasOwnProperty()
方法可以检查对象是否包含特定属性。
const person = {name: "张三",age: 30
};// 使用 in 操作符
console.log("name" in person); // 输出: true
console.log("email" in person); // 输出: false// 使用 hasOwnProperty() 方法
console.log(person.hasOwnProperty("name")); // 输出: true
console.log(person.hasOwnProperty("toString")); // 输出: false (toString 是原型链上的方法)
4. 对象的方法
4.1 定义方法
方法是存储在对象属性中的函数。
const calculator = {add: function(a, b) {return a + b;},subtract: function(a, b) {return a - b;},// ES6 简写语法multiply(a, b) {return a * b;},divide(a, b) {if (b === 0) {return "除数不能为零";}return a / b;}
};console.log(calculator.add(5, 3)); // 输出: 8
console.log(calculator.multiply(5, 3)); // 输出: 15
4.2 this 关键字
在对象方法中,this
指向调用该方法的对象。
const person = {name: "张三",age: 30,sayHello: function() {console.log(`你好,我是${this.name},今年${this.age}岁。`);},birthday: function() {this.age += 1;console.log(`${this.name}生日快乐!现在${this.age}岁了。`);}
};person.sayHello(); // 输出: 你好,我是张三,今年30岁。
person.birthday(); // 输出: 张三生日快乐!现在31岁了。
4.3 箭头函数与 this
注意:在箭头函数中,this
不绑定到调用该函数的对象,而是继承自外层作用域。
const person = {name: "张三",age: 30,// 普通函数,this 指向 person 对象sayHello: function() {console.log(`你好,我是${this.name}。`);},// 箭头函数,this 不指向 person 对象greet: () => {console.log(`你好,我是${this.name}。`); // 这里的 this 可能是全局对象或 undefined(严格模式下)}
};person.sayHello(); // 输出: 你好,我是张三。
person.greet(); // 输出: 你好,我是undefined。(浏览器环境中可能显示为空)
5. 对象的遍历
5.1 for…in 循环
for...in
循环可以遍历对象的所有可枚举属性(包括继承的属性)。
const person = {name: "张三",age: 30,email: "zhangsan@example.com"
};// 遍历对象的所有可枚举属性
for (let key in person) {// 通常使用 hasOwnProperty() 过滤掉继承的属性if (person.hasOwnProperty(key)) {console.log(`${key}: ${person[key]}`);}
}
// 输出:
// name: 张三
// age: 30
// email: zhangsan@example.com
5.2 Object.keys()
Object.keys()
方法返回一个包含对象自身所有可枚举属性名称的数组。
const person = {name: "张三",age: 30,email: "zhangsan@example.com"
};const keys = Object.keys(person);
console.log(keys); // 输出: [ 'name', 'age', 'email' ]// 使用 forEach 遍历
keys.forEach(key => {console.log(`${key}: ${person[key]}`);
});
5.3 Object.values()
Object.values()
方法返回一个包含对象自身所有可枚举属性值的数组。
const person = {name: "张三",age: 30,email: "zhangsan@example.com"
};const values = Object.values(person);
console.log(values); // 输出: [ '张三', 30, 'zhangsan@example.com' ]
5.4 Object.entries()
Object.entries()
方法返回一个包含对象自身所有可枚举属性的键值对数组。
const person = {name: "张三",age: 30,email: "zhangsan@example.com"
};const entries = Object.entries(person);
console.log(entries);
// 输出: [ [ 'name', '张三' ], [ 'age', 30 ], [ 'email', 'zhangsan@example.com' ] ]// 使用 for...of 遍历
for (let [key, value] of entries) {console.log(`${key}: ${value}`);
}
6. 对象的高级特性
6.1 对象解构赋值
ES6 引入了对象解构赋值,可以从对象中提取属性并赋值给变量。
const person = {name: "张三",age: 30,email: "zhangsan@example.com",address: {city: "北京",district: "朝阳区"}
};// 基本解构赋值
const { name, age } = person;
console.log(name); // 输出: 张三
console.log(age); // 输出: 30// 重命名变量
const { name: fullName, email: contactEmail } = person;
console.log(fullName); // 输出: 张三
console.log(contactEmail); // 输出: zhangsan@example.com// 默认值
const { phone = "未知" } = person;
console.log(phone); // 输出: 未知// 嵌套对象解构
const { address: { city, district } } = person;
console.log(city); // 输出: 北京
console.log(district); // 输出: 朝阳区
6.2 对象展开运算符
ES6 引入了展开运算符(...
),可以用于复制对象属性或合并对象。
const person1 = {name: "张三",age: 30
};// 复制对象
const person2 = { ...person1 };
console.log(person2); // 输出: { name: '张三', age: 30 }// 合并对象
const contactInfo = {email: "zhangsan@example.com",phone: "13800138000"
};const completePerson = { ...person1, ...contactInfo };
console.log(completePerson);
// 输出: { name: '张三', age: 30, email: 'zhangsan@example.com', phone: '13800138000' }// 覆盖属性
const updatedPerson = { ...person1, age: 31 };
console.log(updatedPerson); // 输出: { name: '张三', age: 31 }
6.3 Object.assign() 方法
Object.assign()
方法用于将所有可枚举属性从一个或多个源对象复制到目标对象。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3, a: 4 };const result = Object.assign(target, source1, source2);console.log(target); // 输出: { a: 4, b: 2, c: 3 }
console.log(result); // 输出: { a: 4, b: 2, c: 3 } (返回修改后的目标对象)
注意:Object.assign()
执行的是浅拷贝,对于嵌套对象,只会复制引用。
6.4 深度拷贝对象
对于包含嵌套对象的复杂对象,需要进行深度拷贝。
// 使用 JSON 序列化和反序列化(有局限性,不支持函数、Symbol、循环引用等)
const original = {name: "张三",address: {city: "北京"}
};const deepCopy = JSON.parse(JSON.stringify(original));// 修改拷贝后的对象不会影响原对象
deepCopy.address.city = "上海";
console.log(original.address.city); // 输出: 北京
console.log(deepCopy.address.city); // 输出: 上海// 自定义深度拷贝函数(处理更复杂的情况)
function deepClone(obj) {// 处理 null 或非对象类型if (obj === null || typeof obj !== 'object') {return obj;}// 处理日期对象if (obj instanceof Date) {return new Date(obj.getTime());}// 处理数组if (Array.isArray(obj)) {return obj.map(item => deepClone(item));}// 处理普通对象const clonedObj = {};for (let key in obj) {if (obj.hasOwnProperty(key)) {clonedObj[key] = deepClone(obj[key]);}}return clonedObj;
}
6.5 对象的属性描述符
JavaScript 允许通过属性描述符来精确控制对象属性的行为。
const person = {};// 使用 Object.defineProperty() 定义属性
Object.defineProperty(person, 'name', {value: '张三',writable: false, // 是否可写enumerable: true, // 是否可枚举configurable: false // 是否可配置(删除或修改描述符)
});console.log(person.name); // 输出: 张三
person.name = '李四'; // 在非严格模式下静默失败
console.log(person.name); // 输出: 张三(值未改变)// 定义多个属性
Object.defineProperties(person, {age: {value: 30,writable: true,enumerable: true},email: {value: 'zhangsan@example.com',enumerable: false}
});console.log(Object.keys(person)); // 输出: [ 'name', 'age' ] (email 不可枚举)// 获取属性描述符
const nameDescriptor = Object.getOwnPropertyDescriptor(person, 'name');
console.log(nameDescriptor);
// 输出: { value: '张三', writable: false, enumerable: true, configurable: false }// 获取所有属性描述符
const allDescriptors = Object.getOwnPropertyDescriptors(person);
6.6 getter 和 setter
通过 getter 和 setter 可以定义对象的访问器属性,实现属性的读取和赋值控制。
const person = {firstName: "张",lastName: "三",// getter 方法get fullName() {return `${this.firstName}${this.lastName}`;},// setter 方法set fullName(name) {const parts = name.split(" ");this.firstName = parts[0];this.lastName = parts[1] || "";}
};console.log(person.fullName); // 输出: 张三// 使用 setter 设置值
person.fullName = "李 四";
console.log(person.firstName); // 输出: 李
console.log(person.lastName); // 输出: 四
console.log(person.fullName); // 输出: 李四
7. JavaScript 中的继承
JavaScript 使用原型链实现继承。每个对象都有一个原型对象,对象从原型继承方法和属性。
7.1 原型链继承
// 父类构造函数
function Person(name) {this.name = name;
}// 在原型上定义方法
Person.prototype.sayHello = function() {console.log(`Hello, I'm ${this.name}`);
};// 子类构造函数
function Student(name, studentId) {// 调用父类构造函数Person.call(this, name);this.studentId = studentId;
}// 设置子类的原型为父类的实例
Student.prototype = Object.create(Person.prototype);// 修复 constructor 指向
Student.prototype.constructor = Student;// 在子类原型上添加方法
Student.prototype.study = function() {console.log(`${this.name} with ID ${this.studentId} is studying.`);
};// 创建实例
const student = new Student("张三", "1001");
student.sayHello(); // 输出: Hello, I'm 张三 (继承自父类)
student.study(); // 输出: 张三 with ID 1001 is studying. (子类自己的方法)// 检查原型链
console.log(student instanceof Student); // 输出: true
console.log(student instanceof Person); // 输出: true
console.log(student instanceof Object); // 输出: true
7.2 ES6 类的继承
ES6 引入的类语法使继承更加直观。
// 父类
class Person {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, I'm ${this.name}`);}
}// 子类继承父类
class Student extends Person {constructor(name, studentId) {// 调用父类构造函数super(name);this.studentId = studentId;}study() {console.log(`${this.name} with ID ${this.studentId} is studying.`);}
}// 创建实例
const student = new Student("张三", "1001");
student.sayHello(); // 输出: Hello, I'm 张三
student.study(); // 输出: 张三 with ID 1001 is studying.
8. 常用的内置对象
JavaScript 提供了许多内置对象,可以直接使用它们的属性和方法。
8.1 Object 对象
Object
是 JavaScript 中所有对象的基类,提供了许多用于操作对象的静态方法。
// 常用的 Object 方法
Object.create(proto[, propertiesObject]) // 创建新对象
Object.defineProperty(obj, prop, descriptor) // 定义对象的属性
Object.defineProperties(obj, props) // 定义对象的多个属性
Object.getOwnPropertyDescriptor(obj, prop) // 获取属性描述符
Object.getOwnPropertyNames(obj) // 获取所有属性名(包括不可枚举的)
Object.keys(obj) // 获取所有可枚举属性名
Object.values(obj) // 获取所有可枚举属性值
Object.entries(obj) // 获取所有可枚举键值对
Object.assign(target, ...sources) // 合并对象
Object.freeze(obj) // 冻结对象,使其不可修改
Object.seal(obj) // 密封对象,不能添加或删除属性
Object.isFrozen(obj) // 检查对象是否被冻结
Object.isSealed(obj) // 检查对象是否被密封
Object.hasOwnProperty(prop) // 检查对象是否有指定的自有属性
8.2 Array 对象
Array
是用于处理数组的内置对象。
// 创建数组
const arr1 = new Array(1, 2, 3);
const arr2 = [1, 2, 3];// 数组的常用方法
arr.length // 获取或设置数组长度
arr.push(item1, ..., itemN) // 向数组末尾添加元素
arr.pop() // 删除并返回数组最后一个元素
arr.shift() // 删除并返回数组第一个元素
arr.unshift(item1, ..., itemN) // 向数组开头添加元素
arr.slice(start, end) // 返回数组的一部分
arr.splice(start, deleteCount, item1, ..., itemN) // 添加/删除元素
arr.indexOf(searchElement, fromIndex) // 查找元素位置
arr.includes(searchElement, fromIndex) // 检查数组是否包含元素
arr.forEach(callback, thisArg) // 对数组的每个元素执行函数
arr.map(callback, thisArg) // 创建一个新数组,包含对每个元素调用函数的结果
arr.filter(callback, thisArg) // 创建一个新数组,包含通过测试的元素
arr.reduce(callback, initialValue) // 对数组元素执行归约操作
arr.sort(compareFunction) // 对数组元素进行排序
arr.reverse() // 反转数组元素
8.3 String 对象
String
对象用于处理文本(字符串)。
// 创建字符串
const str1 = new String("Hello");
const str2 = "Hello";// 字符串的常用方法
str.length // 获取字符串长度
str.charAt(index) // 返回指定索引位置的字符
str.charCodeAt(index) // 返回指定索引位置字符的 Unicode 值
str.concat(str1, str2, ...) // 连接字符串
str.includes(searchString, position) // 检查字符串是否包含子字符串
str.indexOf(searchValue, fromIndex) // 查找子字符串首次出现的位置
str.lastIndexOf(searchValue, fromIndex) // 查找子字符串最后出现的位置
str.slice(beginIndex, endIndex) // 提取字符串的一部分
str.substring(indexStart, indexEnd) // 提取字符串的子串
str.substr(start, length) // 提取字符串的子串(不推荐使用)
str.split(separator, limit) // 将字符串分割为字符串数组
str.toLowerCase() // 将字符串转换为小写
str.toUpperCase() // 将字符串转换为大写
str.trim() // 去除字符串两端的空白字符
str.replace(searchValue, replaceValue) // 替换字符串中的子串
str.match(regexp) // 查找匹配的字符串
8.4 Number 对象
Number
对象用于处理数值。
// 创建数字
const num1 = new Number(123);
const num2 = 123;// Number 的常用方法和属性
Number.MAX_VALUE // 表示最大的正数
Number.MIN_VALUE // 表示最小的正数
Number.MAX_SAFE_INTEGER // 表示最大的安全整数
Number.MIN_SAFE_INTEGER // 表示最小的安全整数
Number.isNaN(value) // 检查值是否为 NaN
Number.isFinite(value) // 检查值是否为有限数
Number.isInteger(value) // 检查值是否为整数
Number.parseInt(string, radix) // 将字符串转换为整数
Number.parseFloat(string) // 将字符串转换为浮点数
num.toFixed(digits) // 格式化为指定小数位数的字符串
num.toPrecision(precision) // 格式化为指定精度的字符串
num.toString(radix) // 将数字转换为字符串
8.5 Date 对象
Date
对象用于处理日期和时间。
// 创建日期对象
const now = new Date();
const specificDate = new Date(2023, 0, 1); // 2023年1月1日(注意月份从0开始)
const dateString = new Date("2023-01-01");// Date 的常用方法
date.getFullYear() // 获取年份
date.getMonth() // 获取月份(0-11)
date.getDate() // 获取日期(1-31)
date.getDay() // 获取星期几(0-6,0表示星期日)
date.getHours() // 获取小时(0-23)
date.getMinutes() // 获取分钟(0-59)
date.getSeconds() // 获取秒(0-59)
date.getMilliseconds() // 获取毫秒(0-999)
date.getTime() // 获取时间戳(从1970-01-01开始的毫秒数)// 设置日期和时间
date.setFullYear(year)
date.setMonth(month)
date.setDate(date)
date.setHours(hours)
date.setMinutes(minutes)
date.setSeconds(seconds)// 日期格式化
date.toDateString() // 返回日期部分的字符串
date.toTimeString() // 返回时间部分的字符串
date.toISOString() // 返回 ISO 格式的字符串
8.6 Math 对象
Math
对象提供了数学常量和函数。
// Math 的常用属性和方法
Math.PI // 圆周率 π
Math.E // 自然对数的底 e
Math.abs(x) // 绝对值
Math.ceil(x) // 向上取整
Math.floor(x) // 向下取整
Math.round(x) // 四舍五入
Math.max(x1, x2, ...) // 返回最大值
Math.min(x1, x2, ...) // 返回最小值
Math.pow(x, y) // x 的 y 次方
Math.sqrt(x) // 平方根
Math.random() // 返回 0 到 1 之间的随机数
Math.sin(x) // 正弦函数
Math.cos(x) // 余弦函数
Math.tan(x) // 正切函数
Math.log(x) // 自然对数
Math.exp(x) // e 的 x 次方
8.7 Map 和 Set
ES6 引入的 Map
和 Set
是用于存储键值对和唯一值的集合。
// Map 对象
const map = new Map();// 添加元素
map.set("name", "张三");
map.set("age", 30);// 获取元素
console.log(map.get("name")); // 输出: 张三// 检查元素是否存在
console.log(map.has("email")); // 输出: false// 获取 Map 的大小
console.log(map.size); // 输出: 2// 删除元素
map.delete("age");// 遍历 Map
map.forEach((value, key) => {console.log(`${key}: ${value}`);
});for (let [key, value] of map) {console.log(`${key}: ${value}`);
}// Set 对象
const set = new Set([1, 2, 3, 3, 4]);// Set 自动去重
console.log(set.size); // 输出: 4 (重复的 3 只保留一个)// 添加元素
set.add(5);// 检查元素是否存在
console.log(set.has(3)); // 输出: true// 删除元素
set.delete(2);// 遍历 Set
set.forEach(value => {console.log(value);
});for (let value of set) {console.log(value);
}
8.8 JSON 对象
JSON
对象提供了用于解析和生成 JSON 数据的方法。
// JSON 字符串
const jsonString = '{"name":"张三","age":30,"hobbies":["阅读","编程"]}';// 解析 JSON 字符串
const obj = JSON.parse(jsonString);
console.log(obj.name); // 输出: 张三// 将对象转换为 JSON 字符串
const person = {name: "张三",age: 30,hobbies: ["阅读", "编程"]
};const json = JSON.stringify(person);
console.log(json);
// 输出: {"name":"张三","age":30,"hobbies":["阅读","编程"]}// 带缩进的 JSON 字符串
const prettyJson = JSON.stringify(person, null, 2);
console.log(prettyJson);
// 输出格式化的 JSON:
// {
// "name": "张三",
// "age": 30,
// "hobbies": [
// "阅读",
// "编程"
// ]
// }
9. 对象操作的最佳实践
9.1 使用对象字面量创建对象
对象字面量是创建对象最简洁、最易读的方式。
// 推荐
const person = {name: "张三",age: 30
};// 不推荐(除非有特殊原因)
const person = new Object();
person.name = "张三";
person.age = 30;
9.2 使用 ES6 的类语法
对于需要创建多个相似对象的情况,使用 ES6 的类语法比传统的构造函数模式更清晰。
// 推荐
class Person {constructor(name, age) {this.name = name;this.age = age;}sayHello() {console.log(`Hello, I'm ${this.name}`);}
}// 不推荐(除非需要兼容旧浏览器)
function Person(name, age) {this.name = name;this.age = age;
}Person.prototype.sayHello = function() {console.log(`Hello, I'm ${this.name}`);
};
9.3 避免修改内置对象的原型
修改内置对象(如 Object
、Array
等)的原型可能会导致不可预期的问题,应尽量避免。
// 不推荐
Array.prototype.sum = function() {return this.reduce((acc, curr) => acc + curr, 0);
};
9.4 使用对象展开运算符或 Object.assign() 合并对象
const defaults = {timeout: 3000,retries: 3
};const options = {timeout: 5000,url: "https://api.example.com"
};// 推荐
const config = { ...defaults, ...options };// 或者
const config = Object.assign({}, defaults, options);
9.5 优先使用 const 声明对象
除非需要重新赋值整个对象,否则应使用 const
声明对象,这有助于防止意外的对象替换。
// 推荐
const person = {name: "张三",age: 30
};// 仍然可以修改对象的属性
person.age = 31;// 不推荐(除非需要重新赋值整个对象)
let person = {name: "张三",age: 30
};
9.6 使用解构赋值访问对象属性
解构赋值可以使代码更简洁、更易读。
const user = {name: "张三",email: "zhangsan@example.com",role: "admin"
};// 推荐
const { name, email, role } = user;
console.log(name, email, role);// 不推荐
const name = user.name;
const email = user.email;
const role = user.role;
console.log(name, email, role);
9.7 注意 this 的绑定问题
在 JavaScript 中,this
的值取决于函数的调用方式,而不是定义方式。在处理事件处理程序、回调函数等情况时,需要特别注意 this
的绑定。
const person = {name: "张三",greet: function() {console.log(`Hello, I'm ${this.name}`);},delayedGreet: function() {// 在 setTimeout 中,this 不会指向 person 对象setTimeout(function() {console.log(`Hello, I'm ${this.name}`); // this 可能是全局对象或 undefined}, 1000);},delayedGreetFixed: function() {// 方法1: 使用 bindsetTimeout(function() {console.log(`Hello, I'm ${this.name}`);}.bind(this), 1000);// 方法2: 使用箭头函数(继承外层作用域的 this)setTimeout(() => {console.log(`Hello, I'm ${this.name}`);}, 2000);}
};
9.8 安全地访问嵌套对象属性
当访问嵌套对象的属性时,应防止因中间属性不存在而导致的错误。
const user = {profile: {name: "张三",address: {city: "北京"}}
};// 不安全(如果 user.profile 或 user.profile.address 不存在,会抛出错误)
console.log(user.profile.address.city);// 安全的方式1: 逐步检查
let city = "未知";
if (user && user.profile && user.profile.address) {city = user.profile.address.city;
}
console.log(city);// 安全的方式2: 使用可选链操作符(ES11 特性)
console.log(user?.profile?.address?.city || "未知");// 安全的方式3: 使用 try-catch
try {console.log(user.profile.address.city);
} catch (error) {console.log("未知");
}
10. 总结
JavaScript 对象是该语言的核心概念之一,理解和掌握对象的操作对于编写高效、可维护的 JavaScript 代码至关重要。本指南涵盖了 JavaScript 对象的基本概念、创建方法、属性和方法操作、遍历方式、高级特性、继承机制以及常见的内置对象等内容。
通过灵活运用这些知识,您可以更好地组织和管理数据,实现复杂的功能,并编写更加优雅和高效的 JavaScript 代码。随着 JavaScript 语言的不断发展,对象相关的特性也在持续改进,建议保持学习最新的语言特性和最佳实践。