如何在新的 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
所以,我的疑问是:
- 是否有必要像 Java 那样定义 getters 和设置器,或者我可以像
mail.sender
(左右)那样简单地访问字段?
- 如果有必要,如何为每个 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}".`;
}
};
我正在尝试使用新的 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
所以,我的疑问是:
- 是否有必要像 Java 那样定义 getters 和设置器,或者我可以像
mail.sender
(左右)那样简单地访问字段? - 如果有必要,如何为每个 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}".`;
}
};