For the most part, in JavaScript, what you see is what you get. A value’s a value; there are no tricks. Sometimes however, you want a value that’s based on some other values: someone’s full name, for example, is a concatenation of their first and last names. If you have a person object, and you want the users of that object to be able to set the full, first or last name, and see that change immediately reflected in the other values, you’d conventionally build it with functions:
person.setLastName("Smith"); person.setFirstName("Jimmy"); person.getFullName(); // Jimmy Smith
But this is ugly, and requires the users of your object to care that the properties are related; in a more complex example, that might not be as obvious as with names. Luckily, there’s a better way, added in ECMAScript 5.
Meet getters and setters.
HowLet’s make that person object. We want to be able to set the first name, last name or full name, and have it update the other two automagically.
var person = { firstName: "Jimmy", lastName: "Smith", get fullName() { return this.firstName + " " + this.lastName; }, set fullName (name) { var words = name.toString().split(" "); this.firstName = words[0] || ""; this.lastName = words[1] || ""; } } person.fullName = "Jack Franklin"; console.log(person.firstName); // Jack console.log(person.lastName) // Franklin
So what’s going on here?
The get and set keywords are important. Following them is the property they relate to (fullName) and a function body that defines the behaviour when the property is accessed (name = person.fullName) or modified (person.fullName = "Some Name").
These two keywords define accessor functions: a getter and a setter for the fullName property. When the property is accessed, the return value from the getter is used. When a value is set, the setter is called and passed the value that was set. It’s up to you what you do with that value, but what is returned from the setter is the value that was passed in – so you don’t need to return anything.
The official way: Object.defineProperty
Along with the inline method of declaring getters and setters, it can also be done more explicitly via Object.defineProperty (MDN Documentation). This method takes three arguments. The first is the object to add the property to, the second is the name of the property, and the third is an object that describes the property (known as the property’s descriptor). Here’s an example that replicates the above example:
var person = { firstName: "Jimmy", lastName: "Smith" }; Object.defineProperty(person, "fullName", { get: function() { return firstName + " " + lastName; }, set: function(name) { var words = name.split(" "); this.firstName = words[0] || ""; this.lastName = words[1] || ""; } });
The advantage here isn’t immediately apparent. Other than being able to add properties after creating the initial object, is there a real benefit?
When you define a property this way, you can do much more than just define a setter or getter. You may also pass following keys:
configurable (false by default): if this is true, the property’s configuration will be modifiable in future.
enumerable (false by default): if true, the property will appear when looping over the object (for (var key in obj)).
We can also define properties that don’t have explicit getters or setters:
Object.defineProperty(person, "age", { value: 42 });
Now, person.age = 99; will have the desired effect.
OveruseRemember: just because a feature exists, it doesn’t need to be used all the time. Getters and Setters have their use cases, but don’t go over the top, or you’ll most likely end up with a design that’s confusing for those interacting with your objects. Used carefully, they’re very powerful. But with great power comes great responsibility.
Browser support?IE9 and above have full support for Object.defineProperty, along with Safari 5+, Firefox 4+, Chrome 5+ and Opera 12+. If you’re working with Node.js, there’s full support. Don’t you just love Node?!
This article was co-authored with Tom Ashworth. Thanks to Tom for all his help putting this together.
原文链接https://javascriptplayground....
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/83905.html
摘要:使用反射可以在运行时检视类的方法并调用它们。你不能直接得到和,必须扫描类所有的方法并依次检查是否或。首先,我们需要建立和方法的特征方法名称以开始,需要参数,并且返回一个值。查询一个类的和方法的示例代码如下 使用反射可以在运行时检视类的方法并调用它们。这被用来发现类的getters和setters。你不能直接得到getters和setters,必须扫描类所有的方法并依次检查是否gette...
摘要:原文地址设计模式三封装面向对象编程中,一切都是对象,对一个对象的封装,也成了面向对象编程中必不可少的部分。封装方法和别的程序设计语言一样,也只是三种封装概念,,。直接访问和修改破坏了类的封装性。 原文地址:PHP设计模式(三):封装 Introduction 面向对象编程中,一切都是对象,对一个对象的封装,也成了面向对象编程中必不可少的部分。和C/C++,Java,Python等语言一...
摘要:为成员变量生成和函数将光标定位到该变量上单击右键,选择也可以从菜单中选择在弹出的对话框中设置插入的位置,访问属性等 为成员变量生成get和set函数: 将光标定位到该变量上 showImg(https://segmentfault.com/img/bVRKJP?w=303&h=115); 单击右键,选择Source->Generate Getters and Setters......
摘要:用且只用一个完成这一需求。执行时可以增加规则对要变量的合法性进行判断。继承该类时可以重载默认行为。让对象拥有私有成员。理想情况下,应将调用其他函数的函数写在被调用函数的上方。避免位置标记避免在源文件中写入法律评论参考 变量 使用有意义、可读性好的变量 使用 ES6 的 const 声明常量 对功能类似的变量名采用统一的命名风格 使用易于检索名称 举例 // 反例 for (var ...
摘要:系列文章地址文档可以轻松的将对象转换成对象和文档,同样也可以将转换成对象。在项目中如果要引入,可以直接利用或者引入注意,项目已经自动依赖了与,不需要额外重复引入。 Github 系列文章地址 Jackson jackson-databind文档 Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。在项目中如果要引入Jac...
阅读 3646·2023-04-26 02:07
阅读 3153·2021-09-22 15:55
阅读 2536·2021-07-26 23:38
阅读 3121·2019-08-29 15:16
阅读 2011·2019-08-29 11:16
阅读 1750·2019-08-29 11:00
阅读 3585·2019-08-26 18:36
阅读 3165·2019-08-26 13:32