在JavaScript中使用getter和setter可行吗( 二 )


class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } getFullName() { return this.firstName + ' ' + this.lastName; } setFullName(value) { var names = value.split(' '); this.firstName = names[0]; this.lastName = names[1]; }}
类定义了一个严格的接口描述 , 但getter和setter方法使其变得不太严格 。我们已经习惯了臃肿的错误 , 当工作于对象文字和JSON时的键中出现拼写错误的时候 。我希望至少类能够更严格 , 并且在这个意义上 , 提供更好的反馈给开发人员 。
虽然这种情况在定义getter和setter在一个类上的时候没有任何不同 。但它不会阻止任何人拼错 。
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } get fullName() { return this.firstName + ' ' + this.lastName; } set fullName(value) { var names = value.split(' '); this.firstName = names[0]; this.lastName = names[1]; }}
有拼写错误的执行不会给出任何错误:
var person = new Person('Maks', 'Nemisj');console.log(person.fulName);
同样不严格 , 不冗长 , 不可追踪的行为导致可能会出错 。
在我发现这一点后 , 我有一个问题:在使用getter和setter的时候 , 有没有什么可以做的 , 以便于使得类更严格?我发现:有是肯定有 , 但是这值得吗?增加额外层次的复杂性到代码就只是为了使用数量更少的括号?对于API定义 , 也可以不使用getter和setter , 而这样一来就能解决这个问题 。除非你是一个铁杆开发人员 , 并愿意继续进行 , 不然还有另一种解决方案 , 如下所述 。
proxy来帮助?
除了getter和setter方法 , ECMAScript 2015(ES6)还自带proxy对象 。proxy可以帮助你确定委托方法 , 这些委托方法可以在实际访问键执行之前 , 用来执行各种操作 。事实上 , 它看起来像动态getter / setter方法 。
proxy对象可以用来捕捉任何到类的实例的访问 , 并且如果在类中没有找到预先定义的getter或setter就会抛出错误 。
为了做到这一点 , 必须执行下面两个操作:
创建基于Person原型的getter和setter清单 。
创建将测试这些清单的Proxy对象 。
让我们来实现它 。
首先 , 为了找出什么样的getter和setter方法可以用在类Person上 , 可以使用getOwnPropertyNames和getOwnPropertyDescriptor:
var names = Object.getOwnPropertyNames(Person.prototype);var getters = names.filter((name) => { var result = Object.getOwnPropertyDescriptor(Person.prototype, name); return !!result.get;});var setters = names.filter((name) => { var result = Object.getOwnPropertyDescriptor(Person.prototype, name); return !!result.set;});
在此之后 , 创建一个Proxy对象:
var handler = { get(target, name) { if (getters.indexOf(name) != -1) { return target[name]; } throw new Error('Getter "' + name + '" not found in "Person"'); }, set(target, name) { if (setters.indexOf(name) != -1) { return target[name]; } throw new Error('Setter "' + name + '" not found in "Person"'); }};person = new Proxy(person, handler);
现在 , 只要你尝试访问person.fulName , 就会显示Error: Getter “fulName” not found in “Person”的消息 。
希望这篇文章可以帮助你全面了解getter和setter方法 , 以及它们将会带到代码中的危险 。




推荐阅读