Reputation: 1263
I am a backend developer that has developed mostly in Java so I was taught to use setters/getters instead of directly accessing the properties of a class.
Now I'm getting into the frontend world and now got to js/ts. I've seen lot of people access object variables directly without setters and getters as you'd do in Java such as this.person.name
.
Why is this? Is there any advantage on using getter/setter on ts and js if you don't need to add extra code but just to get the value or set it?
Thanks.
Upvotes: 10
Views: 14165
Reputation: 11
BIG difference. Accessing the instance attribute directly means you are strongly coupling your dependent class directly to the source class' attribute.
Whenever you change that attribute to a different type or maybe initialize it in a format that's not expected of the dependent class, you will then need to re-compile this dependent class again.
Is it bad? It depends. The purpose of encapsulation is not security and all that stuff, people say a ton of things without understanding what was really the reason for encapsulation. It's for managing the maintenance profile of your source code by reducing "spaghettification" of pointers.
If you encapsulate the attribute to only be accessible through a method/function, then you decrease the coupling of those two classes because the pointer points to the interface (another name for a function) and not directly to the memory allocation of the attribute. So if you change the memory allocation, you don't end up changing runtime values or recompiling all the classes that point to that allocation. The latter seems not a big deal since we all have crazy fast computers and compilers nowadays, but the former can be a headache to maintain.
With regards to languages, JavaScript started out as a scripting language and not as a bonafide programming language that compiles to an executable. This is one of the reasons why it's mostly okay to access the attributes directly - especially with vanilla JavaScript. It has more freedom and it's not strictly-typed. Developers can do whatever they want with it - as long as they know what they're doing and what they're getting into. That is why there are so many frameworks for JavaScript, each of them enforcing their programming mechanisms differently, some enforce a more object oriented mechanism while others don't.
Java is a strictly-typed full blown compilable programming language, a bit more newbie proof because of explicit rules that can serve as guide. That's why frameworks for Java are mostly limited to boiler plating and dependency injection, and they are easier to grasp because you don't have to learn new mechanisms to understand what's going on.
Upvotes: 1
Reputation: 908
@Pointy is wrong to say: it's really a good idea to forget everything about Java when learning JavaScript. Encapsulation is an object oriented principle of hiding the internal state and behaviour of an object, making your code more maintainable.
In javascript you make tings work with no/messy structure. Typescript is a superset of javascript, this guy is your friend if you are a C#, Java or any other object oriented language programmer.
Example:
in myobject.Ts
export class MyObject {
// private property
private _x: number;
private _z: number;
// public property
y: number;
constructor(private _d?: number) {
this._x = 0;
this.y = 0;
this._z = 0;
this.clog(_d)
}
// access modifier only for _x
get x() {
return this._x;
}
set x(value: number) {
this._x = value;
}
private clog(d: number) {
console.log(d);
}
// arrow function -> public
testf = () => { console.log('value of this._d' , this._d); }
}
then you get in myobject.js this:
export class MyObject {
constructor(_d) {
this._d = _d;
// arrow function -> public
this.testf = () => { console.log('value of this._d', this._d); };
this._x = 0;
this.y = 0;
this.clog(_d);
}
// access modifier
get x() {
return this._x;
}
set x(value) {
this._x = value;
}
clog(d) {
console.log(d);
}
}
Let's use it in main.Ts:
import { MyObject } from './myobject';
let mo = new MyObject(15);
// set a value to the private property x
mo.x = 5;
// get the value of the private property x
// output 5
console.log(mo.x);
with intellisense in vscode you see that it does not show the private property _z and the private function clog().
I suggest you to watch this tutorial and make a better idea. Link
👍
Upvotes: 2
Reputation: 485
A difference between using a getter or setter and accessing object variables directly is that getters/setters are automatically invoked on assignment. So it looks just like a normal property but behind the scenes you can have extra logic (or checks) to be run just before or after the assignment.
So if you decide to add this kind of extra logic to one of the existing object properties already has references, you can convert it to getter/setter style without altering the rest of the code that has access to that property.
let person = {
_age: 50,
set age(newage){
if(typeof newage === 'number'){
this._age = newage;
console.log('valid input')
}
else{
console.log ('Invalid input');
}
}
};
Upvotes: 12