JavaScript Getters and Setters
2015-01-09 14:02
411 查看
http://javascriptplayground.com/blog/2013/12/es5-getters-setters/
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
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:
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.
Let'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.
So what's going on here?
The get and set keywords are important. Following them is the property they relate to (
and a function body that defines the behaviour when the property is accessed (
These two keywords define accessor functions: a getter and a setter for the
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.
Along with the inline method of declaring getters and setters, it can also be done more explicitly via
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:
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:
default): if this is true, the property's configuration will be modifiable in future.
default): if true, the property will appear when looping over the object (
We can also define properties that don't have explicit getters or setters:
This will create
it to the value 42. It's important to note that this property isn't writable. Calling
set, it cannot have a getter or setter. Properties can have values or accessors, not both.
Not only that, but because the
defaults to
not appear when we loop over the object's keys.
If we wanted to make a property writable, we would need to set the
Now,
effect.
Remember: 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.
IE9 and above have full support for
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.
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
personobject, 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.
How
Let'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
fullNameproperty.
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(
falseby
default): if this is true, the property's configuration will be modifiable in future.
enumerable(
falseby
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 });
This will create
person.age, and set
it to the value 42. It's important to note that this property isn't writable. Calling
person.age = 99will have no effect. In this way you can create read-only properties. If a property has a
valuekey
set, it cannot have a getter or setter. Properties can have values or accessors, not both.
Not only that, but because the
enumerableproperty
defaults to
false, this property will
not appear when we loop over the object's keys.
If we wanted to make a property writable, we would need to set the
writableproperty:
Object.defineProperty(person, 'age', { value: 42, writable: true });
Now,
person.age = 99;will have the desired
effect.
Overuse
Remember: 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. Usedcarefully, 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.
相关文章推荐
- Getters and Setters Are Evil or Not Evil?
- JavaScript之Getters和Setters 平台支持等详细介绍
- Using Properties And Synthesize In Objective-C 2.0 For Getters And Setters
- Javascript学习---属性getters和setters
- lombok eclipse 提示 generating getters and setters failed 错误解决方案
- Where Are My Getters and Setters?
- eclipse alt + shift + s generate getters and setters
- Java Reflection(六):Getters and Setters
- WHY YOU SHOULDN'T USE GETTERS AND SETTERS ON ANDROID
- JavaScript之Getters和Setters 平台支持等详细介绍
- Java Reflection - Getters and Setters
- Java Reflection(六):Getters and Setters
- JavaScript—定义 getters 与 setters
- Java Reflection - Getters and Setters
- lombok eclipse 提示 generating getters and setters failed 错误解决方案
- [翻译] JavaScript之Getters和Setters
- 非深入探寻Java反射机制 (Getters and Setters)
- Java Reflection(六):Getters and Setters
- eclipse Generating Getters and Setters Failed
- Browser, Schmouser(the diverge between JScript and JavaScript)