JavaScript的对象访问器

什么是 JavaScript 对象访问器?

在 JavaScript 中,访问器是挂载在对象原生上的函数,可用于获取或设置对象的属性。与直接使用点号(.)操作符访问属性不同,访问器允许在访问或设置属性值时执行自定义逻辑。

访问器包含两种形式:getter 和 setter。

  • getter(获取器) : 用于获取属性值的函数。
  • setter(设置器) : 用于设置属性值的函数。

对象访问器提供了一种控制属性访问和修改方式的方法。 在数据验证、封装和提供计算属性时非常有用。

如何使用对象访问器

我们可以通过对象字面量或使用 Object.defineProperty 方法来定义 getter 和 setter。方法

代码示例:

javascript 复制代码
let person = { // 创建一个对象person
    firstName: "张三", // 定义属性firstName,值为"张三"
    lastName: "李四", // 定义属性lastName,值为"李四"
    get fullName() { // 定义getter函数,用于获取fullName属性
        return `${this.firstName} ${this.lastName}`; // 返回firstName和lastName拼接后的字符串
    },
    set fullName(name) { // 定义setter函数,用于设置fullName属性
        let parts = name.split(' '); // 将传入的name字符串以空格分割成数组
        this.firstName = parts[0]; // 将数组的第一个元素赋值给firstName
        this.lastName = parts[1]; // 将数组的第二个元素赋值给lastName
    }
};

console.log(person.fullName); // 获取fullName属性,输出"张三 李四"
person.fullName = "王五 马六"; // 设置fullName属性,将firstName改为"王五",lastName改为"马六"
console.log(person.firstName); // 输出修改后的firstName,"王五"
console.log(person.lastName); // 输出修改后的lastName,"马六"

在这个例子中,fullName 是一个虚拟属性。它并不直接存在于对象中,而是根据 firstName 和 lastName 派生而来。

使用 Object.defineProperty

另一种定义 getter 和 setter 的方法是使用 Object.defineProperty:

使用 Object.defineProperty 方法定义 getter 和 setter

示例

javascript 复制代码
let person = { // 创建一个对象person
    firstName: "张三", // 定义属性firstName,值为"张三"
    lastName: "李四" // 定义属性lastName,值为"李四"
};

Object.defineProperty(person, 'fullName', { // 使用Object.defineProperty方法为person对象定义fullName属性
    get: function() { // 定义getter函数,用于获取fullName属性
        return `${this.firstName} ${this.lastName}`; // 返回firstName和lastName拼接后的字符串
    },
    set: function(name) { // 定义setter函数,用于设置fullName属性
        let parts = name.split(' '); // 将传入的name字符串以空格分割成数组
        this.firstName = parts[0]; // 将数组的第一个元素赋值给firstName
        this.lastName = parts[1]; // 将数组的第二个元素赋值给lastName
    }
});

console.log(person.fullName); // 获取fullName属性,输出"张三 李四"
person.fullName = "王五 马六"; // 设置fullName属性,将firstName改为"王五",lastName改为"马六"
console.log(person.firstName); // 输出修改后的firstName,"王五"
console.log(person.lastName); // 输出修改后的lastName,"马六"

这里,使用 Object.defineProperty 为 fullName 属性定义了 getter 和 setter。

使用访问器的优点

封装

访问器允许您隐藏对象的内部表示形式,同时提供更清晰的接口。这是面向对象编程中封装的基本原则。

验证

使用访问器进行数据验证

setter 可以用于在更新属性之前验证数据。这可以确保对象保持有效状态

示例

javascript 复制代码
let user = { // 创建一个对象user
    _age: 0, // 定义私有属性_age,值为0
    get age() { // 定义getter函数,用于获取age属性
        return this._age; // 返回_age的值
    },
    set age(value) { // 定义setter函数,用于设置age属性
        if (value < 0) { // 如果传入的值小于0
            console.log("年龄不能为负数"); // 输出错误信息
        } else { // 如果传入的值大于等于0
            this._age = value; // 将值赋给_age
        }
    }
};

user.age = -5; // 尝试设置age属性为负数,触发错误信息
user.age = 25; // 设置age属性为25
console.log(user.age); // 获取age属性,输出25

计算属性

getter 可以用于创建基于其他属性计算得出的属性。这在属性依赖于其他属性值的情况下非常有用。

使用 getter 创建计算属性

示例

javascript 复制代码
let rectangle = { // 创建一个对象rectangle
    width: 10, // 定义属性width,值为10
    height: 5, // 定义属性height,值为5
    get area() { // 定义getter函数,用于获取area属性
        return this.width * this.height; // 返回width和height的乘积
    }
};

console.log(rectangle.area); // 获取area属性,输出50

只读属性

可以通过仅定义 getter 来创建只读属性。

使用 getter 创建只读属性

示例

javascript 复制代码
let car = { // 创建一个对象car
    make: '丰田', // 定义属性make,值为"丰田"
    model: '凯美瑞', // 定义属性model,值为"凯美瑞"
    get description() { // 定义getter函数,用于获取description属性
        return `${this.make} ${this.model}`; // 返回make和model拼接后的字符串
    }
};

console.log(car.description); // 获取description属性,输出"丰田 凯美瑞"
car.description = '本田 雅阁'; // 尝试设置description属性,但不会生效
console.log(car.description); // 再次获取description属性,仍然输出"丰田 凯美瑞"

总结

JavaScript 对象访问器是一项强大特性,可以增加我们与对象属性交互的方式。 通过使用 getter 和 setter,我们可以为对象添加封装、验证、计算属性和只读属性的功能。

相关推荐
羲云4 分钟前
Claude 越界事件之后:Agent 权限设计为什么不能只靠提示词
前端
怕浪猫17 分钟前
Agent 工程化面试:从开发到部署的 5 个关键问题
面试·架构·github
行者全栈架构师18 分钟前
【鸿蒙心迹】鸿蒙网络请求架构实战——@ohos.net.http 到 Axios 封装、拦截器与统一错误处理(HarmonyOS 7.x)
前端·算法·架构
全栈Agent 小李25 分钟前
【无标题】
前端·后端·agent·ai编程·全栈·cursor·mcp
羲云25 分钟前
别让 AI 凭记忆做调研:给 WorkBuddy 接上可核验的实时搜索
前端
只睡四小时32 分钟前
AI 生成 PPTX:11 页课件编译出 429 个形状
javascript·python·pptx·ai生成ppt·ooxml
deli0071 小时前
连接池到底配多大?QPS 和 RT 算一遍,再跑 1 万次请求实测超时率
前端
用户6919026813391 小时前
LangChain 与 LangGraph:从「链」到「图」,一次讲清它们是什么、什么关系
面试·架构·设计
风花一世月1 小时前
🏮 我把三坊七巷做成了能飞的 3D 地图(901 个真实建筑轮廓、20 处景点,在线直接玩)
前端
特立独行的猫A1 小时前
用仓颉语言写一个串口调试助手:cj-tauri 实战
前端