简体   繁体   中英

Difference between using getter&setter and public properties

I am new to JS and was learning abstraction and the use of getter and setters in JS. So, as far as I know, getter and setter can be achieved with object.defineProperty but look guys, what is the reason for giving access to private property via getter and setter instead of public property. Since, with getter we can read private property and with setter we can set new value to private property. Isn't it the same if we use public property which also allows to read value of that public property and set new value to it. I just cannot get why to use getter and setter when we can use public property to achieve both getter and setter. Hope you got my point.

A getter/setter is generally useful for when, on property access, the class wants to do something in addition to simply setting/retrieving the data. For example:

 class MyClass { constructor() { this.setHistory = []; } set item(newVal) { this.setHistory.push(newVal); this._item = newVal; } get item() { return this._item; } } const f = new MyClass(); f.item = 'foo'; f.item = 'bar'; console.log(f.setHistory); 

Above, storing the "history" of what items have previously been set is possible with a setter function. Without the setter function, with only a public item property, the class cannot save the history.

If all a getter/setter is doing is setting or retrieving a value, you're right that it's mostly useless, eg:

 class MyClass { set item(newVal) { this._item = newVal; } get item() { return this._item; } } const f = new MyClass(); f.item = 'foo'; f.item = 'bar'; console.log(f.item); 

Here, the setters and getters aren't doing anything useful at all, so you may well just remove them. Generally, use a setter/getter when you want to do something other than just store/retrieve values.

Setters and getters can also be useful to hide implementation details unimportant to consumers. (For example, assigning to .innerHTML is pretty similar to invoking a setter.)

They can also be useful when debugging, to (for example) log when an object is being changed.

One caveat: the first snippet above doesn't actually use "private" properties, it simply uses the _ -prefix convention to indicate that the property shouldn't be used externally. For a true private property that can't be accessed from the outside, you should define a WeakMap and create the class with an IIFE:

 // with this class, // neither item nor history can be accessed without going through the getters const MyClass = (() => { const privateDatas = new WeakMap(); return class MyClass { constructor() { privateDatas.set(this, { setHistories: [] }); } set item(newVal) { const privates = privateDatas.get(this); privates.setHistories.push(newVal); privates.item = newVal; } get item() { return privateDatas.get(this).item; } getSetHistory() { return privateDatas.get(this).setHistories; // if you want to make sure the internal array doesn't get mutated outside, // return a copy: .setHistories.slice() } } })(); const f = new MyClass(); f.item = 'foo'; f.item = 'bar'; console.log(f.getSetHistory()); 

The field don't really needs to exist for each getter/setter. One example is the Date which I believe only store milliseconds but you can get all the information (it doesn't use the new getter/setter syntax but the concept is the same)


Here is a simple wrapper to Date using the new syntax, hope it makes it more clear.

 class NewSyntaxDate{ constructor(){ this.date = new Date() } get Hours(){return this.date.getHours()} set Hours(h){this.date.setHours(h)} get Minutes(){return this.date.getMinutes()} set Minutes(m){this.date.setMinutes(m)} } let date = new NewSyntaxDate() console.log(date.Hour) console.log(date.Minutes) console.log(date.date) date.Hours = 0 date.Minutes = 0 console.log(date.date) 


Other use include getter-only or setter-only. Data validation (before set to internal field). Alias for other field...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM