我正在尝试使用定义为here的新ECMAScript 2015 JavaScript类来定义一个名为Mail的简单类。
我想出了这个构造函数并尝试了以下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
所以,我怀疑是:
mail.sender
之类的字段(或左右)?答案 0 :(得分:3)
getter和setter基本上是用于捕获对象的属性的get-和set-动作的钩子。它们是函数,但它们似乎是(对于使用此Object的代码),就像属性一样。
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方法,因为我可以直接访问对象字段?
您不需要getter或setter来在JS中公开任何属性,只需定义此属性即可使其公开可用。 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);
答案 1 :(得分:0)
你实际上做的比你需要的多。你不需要按照你的指定使用吸气剂。
试试这个:
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);
答案 2 :(得分:0)
要使用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();
您可以在Mail
函数中返回一个函数,以便能够使用new
关键字实例化新对象。
答案 3 :(得分:0)
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}".`;
}
};