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。问题在哪里?你也许在想:“嘿,我喜欢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';什么也没有。对象是可扩展的,可以动态分配键和值,因此不会有错误在运行时被抛出。这样的行为意味着错误可能显示在用户界面上的某个地方,或者,当某些操作被执行在错误的值上时,而并非是打字错误的时刻。跟踪应该发生在过去但却显示在将来的代码流上的错误是如此有意思。