Javascript面向对象(二)——setter、getter属性
来源:互联网 发布:三维编程叫什么 编辑:程序博客网 时间:2024/06/04 08:17
Javascript面向对象(二)——setter、getter属性
Javascript对象有两种属性,一种是数据属性,我们经常使用比较熟悉;第二种是访问器属性,本质就是获取和设置值的函数,但从代码上好像是正常属性。
Getters 和 setters
访问器属性通过”getter”和”setter”方法表示,在对象中使用get和set文字标识。
let obj = { get propName() { // getter, the code executed on getting obj.propName }, set propName(value) { // setter, the code executed on setting obj.propName = value }};
当obj.proName
调用是,getter方法读取属性,赋值时setter方法调用。示例,我们有user
对象,有name
、surname
两个属性。
let user = {
name: “John”,
surname: “Smith”
};
现在我们想增加fullName
属性,其值为‘John Smith’,我们不想复制粘贴存在的信息,,我们能通过一个访问器实现:
let user = {
name: “John”,
surname: “Smith”,
get fullName() { return `${this.name} ${this.surname}`; }};alert(user.fullName); // John Smith
从外面看,访问器属性好像正常属性,这是访问器属性的思想。我们没有作为一个函数调用user.fullName
,只是正常读取:getter在后台运行。
现在,fullName
仅有一个getter,如果我们打算赋值user.fullName=
,则会报错。让我们来增加setter给user.fullName
修改错误。
let user = { name: "John", surname: "Smith", get fullName() { return `${this.name} ${this.surname}`; }, set fullName(value) { [this.name, this.surname] = value.split(" "); }};// set fullName is executed with the given value.user.fullName = "Alice Cooper";alert(user.name); // Alicealert(user.surname); // Cooper
现在我们有了一个虚拟的属性,可读可写,实际上并不存在。
访问器属性只能使用get/set来访问
属性可以是数据属性或访问器属性,但不能都是。
一旦属性被定义了get prop()
或在set prop()
,则为访问器属性。所以必须通过getter读取、setter赋值。
有时仅有setter或getter,这时正常的,只是这时不能读取或赋值。
访问器描述符
访问器描述符是不同的。对访问器属性,没有value
和writable
,代替他们的是get
和set
函数。
访问器描述可能有:
get
– 无参函数,读取属性时调用,set
– 无参函数, 给属性赋值时调用,enumerable
– 与数据属性一致,configurable
– 与数据属性一致.
示例,使用defineProperty
创建fullName
访问器时,可以get
、set
传递描述符。
let user = { name: "John", surname: "Smith"};Object.defineProperty(user, 'fullName', { get() { return `${this.name} ${this.surname}`; }, set(value) { [this.name, this.surname] = value.split(" "); }});alert(user.fullName); // John Smithfor(let key in user) alert(key);
再次提醒,属性只能是访问器或数据属性,不能都是。如果我们视图给描述符同时提供get
和value
,会报错:
// Error: Invalid property descriptor.Object.defineProperty({}, 'prop', { get() { return 1 }, value: 2});
智能的getter/setter
getter/setter能用作“真实”属性的包装器,实现更多的控制。例如,如果我们想避免user
的名称太短,可以存储name
在一个特殊属性_name
中,然后使用setter过滤赋值。
let user = { get name() { return this._name; }, set name(value) { if (value.length < 4) { alert("Name is too short, need at least 4 characters"); return; } this._name = value; }};user.name = "Pete";alert(user.name); // Peteuser.name = ""; // Name is too short...
技术上,外部代码可以直接访问user._name
,但有个普遍的共识,使用“_”开头的属性,仅在内部使用,外部对象不要直接访问。
兼容性用途
getter和setter的一个好处是,他们可以控制正常数据属性,并在任何时候调整。举例,我们开始实现user
对象使用数据属性name
和age
:
function User(name, age) { this.name = name; this.age = age;}let john = new User("John", 25);alert( john.age ); // 25
但是很快或后来,需求变了,代替age
,我们可能决定去存储birthday
,因为更严格、方便:
function User(name, birthday) {
this.name = name;
this.birthday = birthday;
}
let john = new User("John", new Date(1992, 6, 1));
现在,如何出来原来的代码,他们仍然在使用age
属性?
我们可以尝试找到所有age的代码并修改他们,但这太费时,且如果代码是别人写的,很难去做。另外name
属性对user
对象来说并不多余,在有些地方正是我们需要的,给age
增加一个getter,解决这个问题。
function User(name, birthday) { this.name = name; this.birthday = birthday; // age is calculated from the current date and birthday Object.defineProperty(this, "age", { get() { let todayYear = new Date().getFullYear(); return todayYear - this.birthday.getFullYear(); } });}let john = new User("John", new Date(1992, 6, 1));alert( john.birthday ); // birthday is availablealert( john.age ); // ...as well as the age
现在我们多了一个属性,而且原来的代码也正常工作。
- Javascript面向对象(二)——setter、getter属性
- JavaScript对象属性的getter和setter
- JavaScript对象中属性的getter和setter方法
- JavaScript对象中属性的getter和setter方法
- 【js对象属性的getter和setter】
- js对象属性的getter和setter
- Getter/Setter之深入浅出,对象属性监听
- iOS开发核心语言Objective C —— 面向对象思维、setter和getter方法及点语法
- 属性getter和setter
- 属性getter和setter
- javascript 中的getter,setter
- JavaScript setter与getter
- JS 对象的访问器属性setter getter函数
- get set操作对象属性(getter,setter)js
- JavaScript面向对象(二)——成员属性、静态属性、原型属性与JS原型链
- JavaScript面向对象(二)——成员属性、静态属性、原型属性与JS原型链
- 属性和setter以及getter
- JavaScript面向对象程序设计——属性
- [杂题] Codeforces Gym 101190 NEERC 16 K. Kids Designing Kids
- 动态规划练习一 23:大盗阿福
- win10 x64, python3.6+opencv 3.2
- [sdoi2017][bzoj4821] D2T3 相关分析
- 循环语法注意点
- Javascript面向对象(二)——setter、getter属性
- unix系统之acct()
- Android 客户端Socket 实现及简单封装。
- nyoj-部分和问题
- 编程题(2):组装三角形
- 模板&泛型编程
- 数据库:JDBC编程
- tmp
- 2445小学数学