如你所知 , getter和setter已经成为了JAVAScript的一部分 。它们广泛支持所有的主流浏览器 , 甚至是IE8 。可能看起来getter和setter可以简化代码和节省时间 , 但其实它们会带来隐藏错误 , 并且这些错误第一眼看并不明显 。
文章插图
getter和setter如何工作?
首先小小地总结一下这些是什么东西:
有时候 , 我们希望能允许访问一个会返回动态计算值的属性 , 或者你可能想要反映内部变量的状态 , 而不使用显式的方法调用 。为了说明它们是如何工作的 , 让我们来看一个有着两个属性的person对象 , 这两个属性为:firstName和lastName , 以及一个计算值:fullName 。
var obj = { firstName: "Maks", lastName: "Nemisj"}
计算值fullName会返回firstName和lastName两者的串联 。
Object.defineProperty(person, 'fullName', { get: function () { return this.firstName + ' ' + this.lastName; }});
为了得到fullName的计算值 , 不需要像person.fullName()带可怕的括号 , 只需要使用简单的var fullName = person.fullName 。
这同样适用于setter , 你可以通过使用函数设置值:
Object.defineProperty(person, 'fullName', { set: function (value) { var names = value.split(' '); this.firstName = names[0]; this.lastName = names[1]; }});
使用就和getter一样简单:person.fullName = ‘Boris Gorbachev’ 。这将调用上面定义的函数 , 并分离Boris Gorbachev成firstName和lastName 。
问题在哪里?
【在JavaScript中使用getter和setter可行吗】你也许在想:“嘿 , 我喜欢getter和setter方法 , 它们感觉更自然 , 就像JSON一样 。”你说得对 , 它们的确是这样的 , 但是我们先退一步来看一看fullName在getter和setter之前是如何工作的 。
为得到值 , 我们将使用类似于getFullName()的一些东西 , 以及为了设置值 , 我们将使用person.setFullName(‘Maks Nemisj’) 。
如果拼错函数名 , person.getFullName()写成person.getFulName()会发生什么呢?
JavaScript会给出一个错误:
person.getFulName(); ^TypeError: undefined is not a function
这个错误会在适当的时候适当的地方被触发 。访问函数不存在的对象将触发错误——这是好的 。
现在 , 让我们来看看当用错误的名称来使用setter的时候会发生什么?
person.fulName = 'Boris Gorbachev';
什么也没有 。对象是可扩展的 , 可以动态分配键和值 , 因此不会有错误在运行时被抛出 。
这样的行为意味着错误可能显示在用户界面上的某个地方 , 或者 , 当某些操作被执行在错误的值上时 , 而并非是打字错误的时刻 。
跟踪应该发生在过去但却显示在将来的代码流上的错误是如此有意思 。
seal行不行
这个问题可以通过sealAPI来部分解决 。只要对象是密封的 , 它就不能突变 , 也就是意味着fulName将试图分配一个新键到person对象 , 并且它会失败 。
出于某种原因 , 当我在Node.js V4.0测试这个的时候 , 它没有按照我期待的那样工作 。所以 , 我不能确保这个解决方案 。
而更令人沮丧的是 , 对于setter一点也没有解决方法 。正如我前面提到的 , 对象是可扩展和可故障保护的 , 这意味着访问一个不存在的键不会导致任何错误 。
如果这种情况只适用于对象的文字的话 , 我不会多此一举地写这篇文章 , 但在ECMAScript 2015(ES6)和用类定义getter和setter能力的兴起之后 , 我决定写下关于潜在陷阱的博客 。
类的到来
我知道当前类在一些JavaScript社区不是非常受欢迎 。人们对在函数式/基于原型的语言 , 例如JavaScript中是否需要它们 , 争执不休 。然而 , 事实是 , 类就在ECMAScript 2015(ES6)规范说明中 , 并且将存在于此一段时间 。
对我来说 , 类是指定在类的外部世界(消费者)和应用程序的内部世界之间的定义良好的API的一种方式 。这就是白纸黑字放入规则的抽象 , 并且我们假定这些规则不会很快改变 。
改进person对象 , 做一个它的real类 。person定义了接口用于获取和设置fullName 。
推荐阅读
- python中的for循环在底层是如何开展工作的?
- 如何在JAVA中定义常量?
- 喝茶要有礼 叩指礼你会吗
- 在CentOS 6.5环境中安装VPN 的步骤详解
- JavaScript Fetch API 新手入门指导
- 今日黄金回收420元一克 现在金价多少钱一克
- 仰卧起坐最佳时间,人体代谢的高峰期在下午3-5点
- 以茶待客 敬茶礼仪很重要
- 生活中以茶待客 也要注意礼仪
- 自己在家把高靴改短靴 长靴子能改成短靴子吗