JavaScript对象属性访问器:Getter与Setter详解

JavaScript对象属性访问器:Getter与Setter详解

ko.javascript.info 모던 JavaScript 튜토리얼(The Modern JavaScript Tutorial in Korean ) ko.javascript.info 项目地址: https://gitcode.com/gh_mirrors/ko/ko.javascript.info

什么是属性访问器

在JavaScript中,对象属性主要分为两种类型:

  1. 数据属性:这是我们日常最常用的属性类型,直接存储值
  2. 访问器属性:不直接存储值,而是通过getter和setter方法来控制属性的访问

访问器属性的本质是函数,但对外表现却像普通属性一样使用,这使得它们成为JavaScript中非常强大的特性。

基本语法

访问器属性通过getset关键字在对象字面量中定义:

let obj = {
  get propName() {
    // 当读取obj.propName时执行
    return this._propName;
  },
  
  set propName(value) {
    // 当设置obj.propName = value时执行
    this._propName = value;
  }
};

实际应用示例

计算属性案例

假设我们有一个用户对象,包含名和姓:

let user = {
  firstName: "张",
  lastName: "三",
  
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  },
  
  set fullName(value) {
    [this.firstName, this.lastName] = value.split(" ");
  }
};

console.log(user.fullName); // "张 三"
user.fullName = "李 四";
console.log(user.firstName); // "李"
console.log(user.lastName); // "四"

数据验证案例

访问器属性非常适合用于数据验证:

let user = {
  get age() {
    return this._age;
  },
  
  set age(value) {
    if (value < 0 || value > 120) {
      throw new Error("年龄必须在0到120之间");
    }
    this._age = value;
  }
};

user.age = 25; // 正常
user.age = 150; // 抛出错误

属性描述符差异

访问器属性与数据属性的描述符有所不同:

| 描述符类型 | 数据属性 | 访问器属性 | |------------|----------|------------| | value | 有 | 无 | | writable | 有 | 无 | | get | 无 | 有 | | set | 无 | 有 | | enumerable | 有 | 有 | | configurable | 有 | 有 |

使用Object.defineProperty定义访问器属性:

let obj = {};
Object.defineProperty(obj, 'propertyName', {
  get() {
    return this._value;
  },
  set(value) {
    this._value = value;
  },
  enumerable: true,
  configurable: true
});

高级应用技巧

向后兼容

访问器属性非常适合用于API的演进而不破坏现有代码:

function User(name, birthday) {
  this.name = name;
  this.birthday = birthday;
  
  Object.defineProperty(this, "age", {
    get() {
      let today = new Date();
      return today.getFullYear() - this.birthday.getFullYear();
    }
  });
}

let user = new User("张三", new Date(1990, 5, 15));
console.log(user.age); // 自动计算年龄

私有属性模拟

虽然JavaScript没有真正的私有属性,但可以通过约定和访问器模拟:

class User {
  constructor(name) {
    this._name = name; // 约定: 下划线前缀表示"私有"
  }
  
  get name() {
    return this._name;
  }
  
  set name(value) {
    if (value.length < 3) {
      console.log("名称太短");
      return;
    }
    this._name = value;
  }
}

最佳实践

  1. 命名约定:使用下划线前缀(如_property)表示内部属性
  2. 单一职责:保持getter和setter简单,避免复杂逻辑
  3. 性能考虑:频繁访问的属性可能不适合使用访问器
  4. 一致性:要么同时提供getter和setter,要么明确说明为什么只提供其中一个

访问器属性是JavaScript中强大的工具,合理使用可以使代码更加健壮、灵活且易于维护。

ko.javascript.info 모던 JavaScript 튜토리얼(The Modern JavaScript Tutorial in Korean ) ko.javascript.info 项目地址: https://gitcode.com/gh_mirrors/ko/ko.javascript.info

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计姗群

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值