属性的getter 和setter - 现代JavaScript 教程
文章推薦指數: 80 %
访问器属性由“getter” 和“setter” 方法表示。
在对象字面量中,它们用 get 和 set 表示:. let obj = { get propName() { // 当读取obj.propName 时,getter 起作用 } ...
ZHARعربيENEnglishESEspañolFRFrançaisIDIndonesiaITItalianoJA日本語KO한국어RUРусскийTRTürkçeUKУкраїнськаZH简体中文我们希望将这个开源项目提供给全世界的人。
请帮助我们将教程的内容翻译为你所掌握的语言对应的版本。
购买EPUB/PDF搜索搜索教程路线图LightthemeDarktheme分享عربيEnglishEspañolFrançaisIndonesiaItaliano日本語한국어РусскийTürkçeУкраїнська简体中文有两种类型的对象属性。
第一种是数据属性。
我们已经知道如何使用它们了。
到目前为止,我们使用过的所有属性都是数据属性。
第二种类型的属性是新东西。
它是访问器属性(accessorproperties)。
它们本质上是用于获取和设置值的函数,但从外部代码来看就像常规属性。
getter和setter访问器属性由“getter”和“setter”方法表示。
在对象字面量中,它们用get和set表示:
letobj={
getpropName(){
//当读取obj.propName时,getter起作用
},
setpropName(value){
//当执行obj.propName=value操作时,setter起作用
}
};
当读取obj.propName时,getter起作用,当obj.propName被赋值时,setter起作用。
例如,我们有一个具有name和surname属性的对象user:
letuser={
name:"John",
surname:"Smith"
};
现在我们想添加一个fullName属性,该属性值应该为"JohnSmith"。
当然,我们不想复制粘贴已有的信息,因此我们可以使用访问器来实现:
letuser={
name:"John",
surname:"Smith",
getfullName(){
return`${this.name}${this.surname}`;
}
};
alert(user.fullName);//JohnSmith
从外表看,访问器属性看起来就像一个普通属性。
这就是访问器属性的设计思想。
我们不以函数的方式调用user.fullName,我们正常读取它:getter在幕后运行。
截至目前,fullName只有一个getter。
如果我们尝试赋值操作user.fullName=,将会出现错误:
letuser={
getfullName(){
return`...`;
}
};
user.fullName="Test";//Error(属性只有一个getter)
让我们通过为user.fullName添加一个setter来修复它:
letuser={
name:"John",
surname:"Smith",
getfullName(){
return`${this.name}${this.surname}`;
},
setfullName(value){
[this.name,this.surname]=value.split("");
}
};
//setfullName将以给定值执行
user.fullName="AliceCooper";
alert(user.name);//Alice
alert(user.surname);//Cooper
现在,我们就有一个“虚拟”属性。
它是可读且可写的。
访问器描述符访问器属性的描述符与数据属性的不同。
对于访问器属性,没有value和writable,但是有get和set函数。
所以访问器描述符可能有:
get——一个没有参数的函数,在读取属性时工作,
set——带有一个参数的函数,当属性被设置时调用,
enumerable——与数据属性的相同,
configurable——与数据属性的相同。
例如,要使用defineProperty创建一个fullName访问器,我们可以使用get和set来传递描述符:
letuser={
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);//JohnSmith
for(letkeyinuser)alert(key);//name,surname
请注意,一个属性要么是访问器(具有get/set方法),要么是数据属性(具有value),但不能两者都是。
如果我们试图在同一个描述符中同时提供get和value,则会出现错误:
//Error:Invalidpropertydescriptor.
Object.defineProperty({},'prop',{
get(){
return1
},
value:2
});
更聪明的getter/settergetter/setter可以用作“真实”属性值的包装器,以便对它们进行更多的控制。
例如,如果我们想禁止太短的user的name,我们可以创建一个settername,并将值存储在一个单独的属性_name中:
letuser={
getname(){
returnthis._name;
},
setname(value){
if(value.length<4){
alert("Nameistooshort,needatleast4characters");
return;
}
this._name=value;
}
};
user.name="Pete";
alert(user.name);//Pete
user.name="";//Name太短了……
所以,name被存储在_name属性中,并通过getter和setter进行访问。
从技术上讲,外部代码可以使用user._name直接访问name。
但是,这儿有一个众所周知的约定,即以下划线"_"开头的属性是内部属性,不应该从对象外部进行访问。
兼容性访问器的一大用途是,它们允许随时通过使用getter和setter替换“正常的”数据属性,来控制和调整这些属性的行为。
想象一下,我们开始使用数据属性name和age来实现user对象:
functionUser(name,age){
this.name=name;
this.age=age;
}
letjohn=newUser("John",25);
alert(john.age);//25
……但迟早,情况可能会发生变化。
我们可能会决定存储birthday,而不是age,因为它更精确,更方便:
functionUser(name,birthday){
this.name=name;
this.birthday=birthday;
}
letjohn=newUser("John",newDate(1992,6,1));
现在应该如何处理仍使用age属性的旧代码呢?
我们可以尝试找到所有这些地方并修改它们,但这会花费很多时间,而且如果其他很多人都在使用该代码,那么可能很难完成所有修改。
而且,user中有age是一件好事,对吧?
那我们就把它保留下来吧。
为age添加一个getter来解决这个问题:
functionUser(name,birthday){
this.name=name;
this.birthday=birthday;
//年龄是根据当前日期和生日计算得出的
Object.defineProperty(this,"age",{
get(){
lettodayYear=newDate().getFullYear();
returntodayYear-this.birthday.getFullYear();
}
});
}
letjohn=newUser("John",newDate(1992,6,1));
alert(john.birthday);//birthday是可访问的
alert(john.age);//……age也是可访问的
现在旧的代码也可以工作,而且我们还拥有了一个不错的附加属性。
上一节下一节分享教程路线图评论在评论之前先阅读本内容…如果你发现教程有错误,或者有其他需要修改和提升的地方—请提交一个GitHubissue或pullrequest,而不是在这评论。
如果你对教程的内容有不理解的地方—请详细说明。
使用标签插入只有几个词的代码,插入多行代码可以使用
标签,对于超过10行的代码,建议你使用沙箱(plnkr,JSBin,codepen…)章节对象属性配置课程导航getter和setter访问器描述符更聪明的getter/setter兼容性评论分享在GitHub上编辑© 2007—2022 IlyaKantor关于本项目联系我们
延伸文章資訊
- 1JavaScript Getter and Setter (with Examples) - Programiz
JavaScript Getter and Setter ; Data properties; Accessor properties ; get - to define a getter me...
- 2属性的getter 和setter - 现代JavaScript 教程
访问器属性由“getter” 和“setter” 方法表示。在对象字面量中,它们用 get 和 set 表示:. let obj = { get propName() { // 当读取obj.p...
- 37天搞懂JS進階議題(day05)-getter & setter: 屬性描述器
7天搞懂JS進階議題(day05)-getter & setter: 屬性描述器. February 27, 2020. 本系列文章討論JS 物件導向設計相關的特性。 不含CSS,不含HTML!...
- 4Property getters and setters - The Modern JavaScript Tutorial
Getters and setters ... Accessor properties are represented by “getter” and “setter” methods. In ...
- 5JavaScript Object Accessors - W3Schools
ECMAScript 5 (ES5 2009) introduced Getter and Setters. Getters and setters allow you to define Ob...