小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2024-10-21 / 4 阅读
0
0

JavaScript getter和setter详解以及和普通函数的区别

详细解释JavaScript中的getter和setter,以及它们与普通函数的区别,并提供一个实际开发中的例子。

Getter 和 Setter

Getter

  • 定义:getter 是一种特殊的方法,用于读取对象的属性值。它允许您定义一个看起来像普通属性但实际上是一个方法的东西,当访问这个属性时,getter 方法会被自动调用。
  • 用途:通常用于封装属性的读取逻辑,使得属性的获取更加灵活和安全。例如,可以在 getter 中添加验证逻辑、计算属性值等。

Setter

  • 定义:setter 是一种特殊的方法,用于设置对象的属性值。它允许您定义一个看起来像普通属性但实际上是一个方法的东西,当设置这个属性时,setter 方法会被自动调用。
  • 用途:通常用于封装属性的设置逻辑,确保属性值的有效性和一致性。例如,可以在 setter 中添加验证逻辑、转换属性值等。

Getter 和 Setter 与普通函数的区别

  1. 调用方式不同

    • 普通函数:需要通过括号 () 来调用,即使没有参数也需要加上括号。
    • Getter 和 Setter:像访问或设置普通属性一样直接使用点 . 操作符来调用,不需要加括号。
  2. 用途不同

    • 普通函数:可以用于执行任何类型的逻辑,并且通常用于执行一系列的操作,可能返回也可能不返回结果。
    • Getter 和 Setter:主要用于封装属性的读取和设置逻辑,使得属性的访问更加灵活和安全。
  3. 可设置性不同

    • 普通函数:可以通过赋值操作来更改。
    • Getter 和 Setter:一旦定义,除非重新定义,否则不能直接更改其值,只能通过 setter 来改变相关的状态。
  4. 默认行为

    • 普通函数:没有默认的行为,它们的行为完全取决于开发者如何编写。
    • Getter:默认行为是返回一个值,通常是为了提供属性的访问控制或者进行一些计算后返回结果。
    • Setter:默认行为是设置一个值,通常是为了确保属性值的有效性和一致性。

实战例子

假设我们有一个 Person 类,我们需要确保 age 属性始终是非负数,并且在获取 age 属性时返回一个友好的消息。

class Person {
  constructor(name, age) {
    this.name = name;
    this._age = age; // 使用下划线表示这是一个私有属性
  }

  // Getter
  get age() {
    return `${this.name} is ${this._age} years old.`;
  }

  // Setter
  set age(newAge) {
    if (newAge < 0) {
      throw new Error('Age cannot be negative.');
    }
    this._age = newAge;
  }
}

// 创建一个 Person 实例
const person = new Person('Alice', 30);

// 使用 getter 获取 age 属性
console.log(person.age); // 输出: Alice is 30 years old.

// 使用 setter 设置 age 属性
person.age = 35;
console.log(person.age); // 输出: Alice is 35 years old.

// 尝试设置一个负数年龄
try {
  person.age = -10;
} catch (error) {
  console.error(error.message); // 输出: Age cannot be negative.
}

解释

  1. 构造函数constructor 方法初始化 name_age 属性。这里 _age 前面加了一个下划线,表示这是一个私有属性,不应该直接从外部访问。
  2. Getterget age 方法返回一个友好的消息,包含姓名和年龄。
  3. Setterset age 方法检查新的年龄是否为非负数,如果是负数则抛出错误,否则更新 _age 属性。
  4. 使用示例:创建一个 Person 实例,使用 getter 获取年龄信息,使用 setter 设置新的年龄,并尝试设置一个负数年龄以触发错误。

通过这种方式,getter 和 setter 不仅提供了对属性的封装,还增加了代码的可读性和安全性。

JavaScript getter和setter 像普通方法,但是传参和调用不需要加括号,这样理解对吗,因为普通函数也能对属性赋值,也能进行一些逻辑判断?

理解基本上是对的,但在细节上需要做一些澄清。

在JavaScript中,getter和setter是一种特殊的属性,它们允许你以更自然的方式控制对象属性的读取和写入行为。这些getter和setter看起来就像是普通的属性,但实际上它们背后关联着方法,这些方法可以在属性被读取或设置时执行特定的逻辑。

Getter 和 Setter 的定义

你可以使用 get关键字来定义一个getter,使用 set关键字来定义一个setter。例如:

let obj = {
    _value: 0,

    get value() {
        console.log('Getter called');
        return this._value;
    },

    set value(newVal) {
        console.log('Setter called with', newVal);
        if (newVal > 0) {
            this._value = newVal;
        } else {
            console.log('Value must be positive');
        }
    }
};

在这个例子中,当你尝试访问 obj.value时,实际上调用了getter方法;而当你试图给 obj.value赋值时,setter方法会被触发。

调用方式

  • Getter:当访问属性时,不需要使用括号,就像访问普通的属性一样:

    console.log(obj.value); // 输出: Getter called, 然后是0
    
  • Setter:当设置属性值时,同样不需要使用括号,就像设置普通的属性一样:

    obj.value = 5; // 输出: Setter called with 5
    

对比普通方法

普通方法调用时需要使用括号,即使没有参数也一样。例如:

let obj = {
    method: function() {
        console.log('Method called');
    }
};

obj.method(); // 调用方法,输出: Method called

普通方法也可以用来修改对象的状态或执行复杂的逻辑,但是它们的调用语法与getter和setter不同。

总结来说,getter和setter提供了更简洁的接口来访问和修改对象状态,同时隐藏了背后的逻辑处理,使得代码更加清晰和易于维护。


评论