如何在新的ECMAScript 2015 JavaScript类中定义getter和setter
我正在尝试使用新的ECMAScript 2015 JavaScript类定义一个名为Mail的简单类 我提出了这个构造函数并尝试了以下getter:如何在新的ECMAScript 2015 JavaScript类中定义getter和setter,javascript,Javascript,我正在尝试使用新的ECMAScript 2015 JavaScript类定义一个名为Mail的简单类 我提出了这个构造函数并尝试了以下getter: class Mail { constructor(sender, date, subject, text) { this.sender = sender; this.date = date; this.subject = subject; this.text = text;
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
因此,我的疑问是:
mail.sender这样的字段
getter和setter基本上是捕捉对象的属性的get和set操作的钩子。它们是函数,但它们(对于使用此对象的代码)看起来像属性
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;
}
}
编辑:
这是否意味着我可以忽略get和set方法,因为我可以直接访问对象字段
在JS中,您不需要getter或setter来公开任何属性,只需定义此属性即可使其公开。JS的工作方式正好相反,您必须付出额外的努力使事情私有化(请参见闭包)。在JS中,默认情况下所有内容都是公共的
但您可以使用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);
事实上你做的比你需要的多。您不需要指定的getter 试试这个:
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邮件{
构造函数(发送方){
这个。_sender=发送方;
}
获取发件人(){
return“Sender:+此.\u Sender;
}
设置发送器(val){
此._sender=val.toLowerCase();
}
}
const m=新邮件(“测试”);
console.log(m.sender);//=>“发件人:测试”
m、 发送者=“测试”;
console.log(m.sender);//=>“Sender:test”
JavaScript没有类的概念。
class
关键字只是语法上的糖分
类所做的是为您生成一个构造函数
const Person=class{//或`class Person`
建造师(姓名){
this.name=名称;
}
说(味精){
返回`${this.name}表示:“${msg}”;
}
}
这与使用以下代码将实现的完全相同
const Person=函数(名称){
this.name=名称;
};
Person.prototype={
说(味精){
返回`${this.name}表示:“${msg}”;
}
};
如果需要私有变量,则必须使用闭包
const Person=class{//或`class Person`
建造师(姓名){
this.getName=()=>name;
this.setName=(newName)=>{
name=newName;
}
}
说(味精){
返回`${this.getName()}表示:“${msg}”。`;
}
}
设p=新人(“我”);
console.log(p.name);//未定义
console.log(p.getName());/'我的
p、 设置名称(“他”);
console.log(p.getName());/'他是
console.log(p.say('something');/'他说:“有些东西。”
我建议您不要使用类
,并避免使用新的
。
如果需要对象,只需使用工厂函数
:
const Person=函数(名称){
让person=Object.create(person.prototype);
person.name=姓名;
返回人;
};
Person.prototype={
说(味精){
返回`${this.name}表示:“${msg}”;
}
};
要使用getter和setter,只需使用并设置属性即可mail.sender
@nicovank,这样我就可以直接访问所需的邮件属性了?Java中没有任何封装问题吗?如果您在当前状态下使用mail.sender
,您将得到无限递归。@nicovank抱歉,我想我误解了。你是说我可以按上面的方式获取,当调用mail.sender
时,它会自动调用该getter,对吗?是的。我会写一个详细的答案,毕竟它真的陷入了无限递归。这是否意味着我可以忽略get和set方法,因为我可以直接访问对象字段?(避免陷入无限递归的唯一方法是,如果我更改get/set name)@rcbauer是的,如果您只需要一个简单的属性来保存值,就不需要getter/setter。@rcbauer它陷入无限递归,因为您的getterget sender(){return this.sender;}
正在调用自身<代码>返回此消息。发送者正在再次调用获取者。这就是为什么我在属性前面加了下划线(这是JS中的常见模式)。以下划线开头的属性应视为私有属性,而不是API的一部分。模块模式不允许他创建新对象。这就是工厂模式