繁体   English   中英

使用getter&setter和公共属性之间的区别

[英]Difference between using getter&setter and public properties

我是JS的新手,正在学习JS中的抽象以及getter和setter的使用。 因此,据我所知,可以使用object.defineProperty来实现getter和setter,但是伙计们,是什么原因允许通过getter和setter而不是公共财产访问私有财产。 因为,使用getter可以读取私有财产,而使用setter可以将新值设置为私有财产。 如果我们使用公共财产也可以读取公共财产的价值并为其设置新的价值,这是不一样的。 当我们可以使用公共属性同时实现getter和setter时,我只是无法理解为什么要使用getter和setter。 希望你明白我的意思。

通常,在属性访问时,除了简单地设置/检索数据之外,类还需要执行某些操作时,getter / setter很有用。 例如:

 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); 

在上面,可以使用设置功能存储以前设置了哪些项目的“历史记录”。 如果没有setter函数,则只有一个公共item属性,该类将无法保存历史记录。

如果getter / setter所要做的只是设置或检索值,那么您说对了,它几乎没有用,例如:

 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); 

在这里,setter和getter根本没有做任何有用的事情,因此您可以删除它们。 通常,当您要执行除存储/检索值之外的其他操作时,请使用setter / getter。

setter和getter还可用于隐藏对消费者不重要的实现细节。 (例如,分配给.innerHTML 调用设置器非常相似 。)

它们在调试时也很有用,例如在更改对象时记录日志。

一个警告:上面的第一个代码片段实际上并不使用“私有”属性,它只是使用_ -prefix约定来指示该属性不应在外部使用。 对于无法从外部访问的真实私有属性,应定义WeakMap并使用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()); 

每个getter / setter都不需要真正存在该字段。 一个示例是Date ,我相信它只存储毫秒,但是您可以获得所有信息(它不使用新的getter / setter语法,但是概念相同)


这是使用新语法的Date的简单包装,希望可以使它更加清晰。

 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) 


其他用途包括仅使用getter或仅使用setter。 数据验证(设置为内部字段之前)。 其他领域的别名...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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