在本教程中,您将了解 JavaScript getter 和 setter 以及如何有效地使用它们。

JavaScript getter 和 setter 简介

以下示例定义一个名为 Person

class Person {
    constructor(name) {
        this.name = name;
    }
}

let person = new Person("John");
console.log(person.name); // John

Person 类有一个属性 name 和一个构造函数。构造函数将 name 属性初始化为字符串。

有时,您不希望像这样直接访问 name 属性:

person.name

因此,您可能想出一对操作 name 属性的方法。例如:

class Person {
    constructor(name) {
        this.setName(name);
    }
    getName() {
        return this.name;
    }
    setName(newName) {
        newName = newName.trim();
        if (newName === '') {
            throw 'The name cannot be empty';
        }
        this.name = newName;
    }
}

let person = new Person('Jane Doe');
console.log(person); // Jane Doe

person.setName('Jane Smith');
console.log(person.getName()); // Jane Smith

在此示例中,Person 类具有 name 属性。此外,它还有两个额外的方法 getName()setName()

getName() 方法返回 name 属性的值。setName() 方法首先删除 newName 参数两端的空格,如果为空则抛出异常。然后将分配 newName 参数的值赋值 name 属性。

constructor() 方法调用  setName() 来初始化 name 属性:

constructor(name) { this.setName(name);}

getName()setName() 方法在其他编程语言(如 Java 和 C++ )中称为 getter 和 setter。

ES6 提供关键词 get 和 set 定义 getter 和 setter 的方法。例如:

class Person {
    constructor(name) {
        this.name = name;
    }
    get name() {
        return this._name;
    }
    set name(newName) {
        newName = newName.trim();
        if (newName === '') {
            throw 'The name cannot be empty';
        }
        this._name = newName;
    }
}

代码是如何运行的。

首先,将 name 属性更改为 _name 以避免与 getter 和 setter 的名称冲突。其次,getter 使用 get 关键词后跟方法名:

get name() {
    return this._name;
}

要调用 getter,请使用下面语法:

let name = person.name;

当 JavaScript 看到对 Person 类访问 name 属性时,它会检查 Person 类是有 name 属性。

如果没有,JavaScript 会检查 Person 类是否有绑定到 name 属性的方法。在此示例中,name() 方法通过关键词 get 绑定到 name 属性。一旦 JavaScript 找到 getter 方法,它就会执行 getter 方法并返回一个值。

第三,setter 使用 set 关键字后跟方法名:

set name(newName) {
    newName = newName.trim();
    if (newName === '') {
        throw 'The name cannot be empty';
    }
    this._name = newName;
}

当你为 name 属性赋值时,JavaScript 将会调用 name的 setter 方法 name(),如下所示:

person.name = 'Jane Smith';

如果一个类只有 getter 而没有 setter 而你试图使用 setter,则更改不会生效。请参阅以下示例:

class Person {
    constructor(name) {
        this._name = name;
    }
    get name() {
        return this._name;
    }
}

let person = new Person("Jane Doe");
console.log(person.name);

// 尝试改变 name 属性
person.name = 'Jane Smith';
console.log(person.name); // Jane Doe

在这个例子中,Person 类的 name属性有 getter 但没有 setter。它尝试调用 setter。但是,更改不会生效,因为 Person 类没有 name 属性的 setter。

在对象字面量使用 getter

以下示例定义了一个调用的 getterlatest以返回对象的最新参加者meeting

let meeting = {
    attendees: [],
    add(attendee) {
        console.log(`${attendee} joined the meeting.`);
        this.attendees.push(attendee);
        return this;
    },
    get latest() {
        let count = this.attendees.length;
        return count == 0 ? undefined : this.attendees[count - 1];
    }
};

meeting.add('John').add('Jane').add('Peter');
console.log(`The latest attendee is ${meeting.latest}.`);

输出:

John joined a meeting.
Jane joined a meeting.
Peter joined a meeting.
The latest attendee is Peter.

结论

  • 使用 getset 关键词为 JavaScript 类或对象定义  getter 和 setter。
  • 关键词 get 将对象属性绑定到一个方法,该方法将在访问该属性时调用。
  • 关键词 set 将对象属性绑定到一个方法,该方法将在赋值给属性时调用。