如何在新的 ECMAScript 2015 中定义 getter 和 setter JavaScript 类

How to define getters and setters in new ECMAScript 2015 JavaScript classes

我正在尝试使用新的 ECMAScript 2015 JavaScript classes 定义一个简单的 class 称为 Mail here

我想出了这个构造函数并尝试了以下 getter:

class Mail {
   constructor(sender, date, subject, text) {
        this.sender = sender;
        this.date = date;
        this.subject = subject;
        this.text = text;
   }
   get sender() {
       return this.sender;
   }
}

但是当我尝试使用那个方法时,它没有用。

var mail = new Mail("@mail.com", Date.now(), "Testing", "Text");
console.log(mail.sender());

返回:

TypeError: mail.sender is not a function

所以,我的疑问是:

  1. 是否有必要像 Java 那样定义 getters 和设置器,或者我可以像 mail.sender(左右)那样简单地访问字段?
  2. 如果有必要,如何为每个 class 实例变量正确定义 getter 和设置器?

getter 和 setter 基本上是用于捕获对象的 属性 的获取和设置操作的挂钩。它们是函数,但它们看起来 (对于使用此对象的代码) 就像 属性.

var mail = new Mail("@mail.com", Date.now(), "Testing", "Text");
console.log(mail.sender); //no brackets

并且如果您添加 setter、main.sender = "@foo.bar"

而且我想知道您的代码没有陷入无限递归,因为您的 getter 调用了自身。

class Mail {
   constructor(sender, date, subject, text) {
        this._sender = sender;
        this._date = date;
        this._subject = subject;
        this._text = text;
   }

   //this IS `this.sender`!
   //it should not `return this.sender`, since this would call this getter again, 
   //and you get stuck in an infinite recursion.
   get sender() {
       return this._sender;
   }

   //and a possible setter, that handles 
   //instance.sender = whatever;
   set sender(value) {
       this._sender = value;
   }
}

编辑:

Does this mean that I can just ignore get and set methods because I can directly access object field?

你不需要 getter 或 setter 来在 JS 中创建任何 属性 public,只需定义这个 属性 就可以 public可用。 JS 以相反的方式工作,你必须付出额外的努力才能使事情变得私有 (参见闭包)。在 JS 中,默认情况下一切都是 public.

但您可以使用 getter(和 setter)来完成其他任务,例如:

class Person{
    constructor(firstName, lastName){
        //regular public properties
        this.firstName = firstName;
        this.lastName = lastName;
    }

    //a composed value, that you can access like a property
    get fullName(){
        return this.firstName + " " + this.lastName;
    }

    //you could also add a setter like this
    set fullName(value){
        [this.firstName, this.lastName] = value.split(/\s+/g);
    }
}

var john = new Person("John", "Doe");
console.log(john.fullName);

你实际上做了比你需要做的更多的事情。您不需要指定的吸气剂。

试试这个:

class Mail {
 constructor(sender, date, subject, text) {
    this.sender = sender;
    this.date = date;
    this.subject = subject;
    this.text = text;
  }
}

var mail = new Mail("@mail.com", Date.now(), "Testing", "Text");
console.log(mail.sender);

要使用getter和setter,您只需使用并设置属性。在你的情况下:mail.sender。如果您正在使用该值,这将调用 getter,如果您覆盖当前值,则将调用 setter。

class Mail {
    constructor(sender) {
        this._sender = sender;
    }

    get sender() {
        return "Sender: " + this._sender;
    }

    set sender(val) {
        this._sender = val.toLowerCase();
    }
}

const m = new Mail("TEST");
console.log(m.sender); // => "Sender: TEST"

m.sender = "TEST";
console.log(m.sender); // => "Sender: test"

请注意,我使用 _sender 来存储值以防止出现 Maximum call stack size exceeded error

您可以像使用任何其他 属性 一样使用 属性,它会自动调用 getter 或 setter。


如果您正在寻找的是封装,您可以这样设计 类:

const Mail = (function() {
    let sender; // this is "private"

    return {
        title: "public", // This is public
        get sender() {
            return sender;
        },
        // ...
    };
});

在这种情况下,您将创建新的 Mail 对象,如下所示:

const mail = Mail();

您可以 return Mail 函数中的一个函数,以便能够使用 new 关键字实例化新对象。

JavaScript没有类的概念。 class 关键字只是语法糖。

class 所做的是,它会为您生成一个 constructor function

const Person = class { // or `class Person`
    constructor(name) {
        this.name = name;
    }

    say(msg) {
        return `${this.name} says: "${msg}".`;
    }
}

完全一样,您将通过以下代码实现。

const Person = function(name) {
    this.name = name;
};

Person.prototype = {
    say(msg) {
        return `${this.name} says: "${msg}".`;
    }
};

如果你需要私有变量,你必须使用闭包。

const Person = class { // or `class Person`
    constructor(name) {
        this.getName = () => name;
        this.setName = (newName) => {
            name = newName;
        }
    }

    say(msg) {
        return `${this.getName()} says: "${msg}".`;
    }
}

let p = new Person('me');
console.log(p.name); // undefined
console.log(p.getName()); // 'me'
p.setName('he');
console.log(p.getName()); // 'he'
console.log(p.say('something')); // 'he says: "something".'

我建议您不要使用 class 并避免使用 new。 如果你需要一个对象,你可以简单地使用 factory functions:

const Person = function(name) {
    let person = Object.create(Person.prototype);
    person.name = name;
    return person;
};

Person.prototype = {
    say(msg) {
        return `${this.name} says: "${msg}".`;
    }
};