Reputation:
I'm trying do define a simple class called Mail using the new ECMAScript 2015 JavaScript classes as defined here.
I came up with this constructor and tried the following 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;
}
}
But when I tried to use that method, it didn't work.
var mail = new Mail("@mail.com", Date.now(), "Testing", "Text");
console.log(mail.sender());
Returned:
TypeError: mail.sender is not a function
So, my doubt is:
mail.sender
(or so)?Upvotes: 1
Views: 1290
Reputation: 12657
getter and setter are basically hooks to capture get- and set- actions for properties of an object. They are functions, but they seem (to the code that uses this Object) like a property.
var mail = new Mail("@mail.com", Date.now(), "Testing", "Text");
console.log(mail.sender); //no brackets
and if you add a setter, main.sender = "@foo.bar"
.
And I'm wondering that your code didn't get stuck in an infinite recursion, since your getter called itself.
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;
}
}
Edit:
Does this mean that I can just ignore get and set methods because I can directly access object field?
you don't need getter or setter to make any property public in JS, simply defineing this property makes it public available. JS works the other way around, you have to take additional efforts to make things private (see closures). In JS everything is by default public.
But you can use getter (and setter) to fulfil additional tasks, like:
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);
Upvotes: 4
Reputation: 3227
To use getters and setters, you just need to use and set the property. in your case: mail.sender
. This will call the getter if you are using the value, or the setter if you are overriding the current value.
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"
Note that I used _sender
to store the value to prevent a Maximum call stack size exceeded error
.
You can use the property like any other property, and it will automatically call the getter or setter.
If what you were looking for is encapsulation, you could design your classes like so:
const Mail = (function() {
let sender; // this is "private"
return {
title: "public", // This is public
get sender() {
return sender;
},
// ...
};
});
In this case, you would then create new Mail
objects like so:
const mail = Mail();
You could return a function in the Mail
function in order to be able to instantiate new objects with the new
keyword.
Upvotes: 0
Reputation: 329
JavaScript has no concept of classes.
The class
keyword is just syntactic sugar.
What a class
do is, it generates a constructor function
for you.
const Person = class { // or `class Person`
constructor(name) {
this.name = name;
}
say(msg) {
return `${this.name} says: "${msg}".`;
}
}
That's exactly the same, what you will achieve with the following code.
const Person = function(name) {
this.name = name;
};
Person.prototype = {
say(msg) {
return `${this.name} says: "${msg}".`;
}
};
If you need private variables, you have to work with closures.
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".'
I advice you to not use class
and to avoid new
.
If you need an object, you simply can use 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}".`;
}
};
Upvotes: 0
Reputation: 531
You actually did more than you need to. You don't need getters as you specified.
Try this:
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);
Upvotes: 0