JavaScript Note 2022.09.07 Accessor property
关于JS对象的访问器属性(Accessor property)(JS对象属性的getter与setter)
1.认识访问器属性
{
{
let person = {
firstName: "Hello",
lastName: "World",
fullName() {
return this.firstName + " " + this.lastName;
}
}
console.log("------------------------ 2 ------------------------");
console.log(person.fullName);
/**
*
* ƒ fullName() {
* return this.firstName + " " + this.lastName;
* }
*
*/
console.log(person.fullName());
}
// fullName是个函数,需要调用才能得到值
// 但我想将其设为像firstName、lastName这样的普通属性,想直接通过person.fullName得到值
// 就像是Vue中的computed与methods似的,现在想将methods改写为computed
/**
* 为什么使用 Getter 和 Setter?
* 它提供了更简洁的语法
* 它允许属性和方法的语法相同
* 它可以确保更好的数据质量(我猜是说Vue的computed之于methods)
* 有利于后台工作
*/
{
let person = {
firstName: "Hello",
lastName: "World",
get fullName() {
return this.firstName + " " + this.lastName;
}
}
console.log("------------------------ 3 ------------------------");
console.log(person.fullName);
// console.log(person.fullName());//Uncaught TypeError: person.fullName is not a function
// fullName 不是函数了!
// 从外表看,访问器属性(accessor property)看起来就像一个普通属性。这就是访问器属性的设计思想。
person.fullName = "Captain America";//不报错,但它是无效的!
console.log(person.fullName);//Hello World
for(let key in person) {
console.log(key + ": " + person[key]);
}
// firstName: Hello
// lastName: World
// fullName: Hello World
}
}
{
let person = {
firstName: "Hello",
lastName: "World",
get fullName() {
return this.firstName + " " + this.lastName;
},
set fullName(value) {
//Destructuring Assignment 解构 -> 赋值
[this.firstName, this.lastName] = value.split(" ");
}
}
console.log("------------------------ 4 ------------------------");
console.log(person.fullName);//Hello World
person.fullName = "Captain America";
console.log(person.fullName);//Captain America
}
{
{
let person = {
firstName: "Hello",
lastName: "World",
}
Object.defineProperty(person, 'fullName', {
get() {
return this.firstName + " " + this.lastName;
},
set(value) {
[this.firstName, this.lastName] = value.split(" ");
}
})
console.log("------------------------ 5 ------------------------");
console.log(person.fullName);//Hello World
person.fullName = "Captain America";
console.log(person.fullName);//Captain America
for(let key in person) {
console.log(key + ": " + person[key]);
}
// firstName: Captain
// lastName: America
// 通过 Object.defineProperty 定义的属性还是有些特殊的:for循环访问不到...........
}
}
2.访问器属性的实用之处
①.限制属性的访问(get)与修改(set)
{
//实用之处①:限制访问(get)与修改(set)
let user = "visitor";
let person = {
firstName: "Hello",
lastName: "World",
get fullName() {
if(user === "visitor") {
alert("Access Denied!");
return ;
}
return this.firstName + " " + this.lastName;
},
set fullName(value) {
if(value.length < 6) {
alert("The value is too short!");
return;
}
[this.firstName, this.lastName] = value.split(" ");
}
}
console.log("------------------------ 6 ------------------------");
console.log(person.fullName);//alert("Access Denied!");
user = "admin";
console.log(person.fullName);//Hello World
person.fullName = "123";
console.log(person.fullName);//alert("The value is too short!");
person.fullName = "Captain America";
console.log(person.fullName);//Captain America
}
②.让代码向过去兼容(Backward Compatibility)
{
//前人:过去的人 向前兼容:向未来兼容
//后人;将来的人 向后兼容:向过去兼容
//实用之处②:向后(过去)兼容(Backward Compatibility)
{
console.log("------------------------ 7 ------------------------");
//从前的代码
function Person(name, age) {
this.name = name;
this.age = age;
}
let Mike = new Person("Mike", 22);
//从前某个文件某处代码
console.log("Mike's age is " + Mike.age);//Mike's age is 22
}
{
//某一天部分代码重构了
function Person(name, birthday) {
this.name = name;
this.birthday = birthday;
Object.defineProperty(this, "age", {
get() {
let todayYear = 2022;
return todayYear - this.birthday;
}
});
}
let Mike = new Person("Mike", 2000);
//从前某个文件某处代码
console.log("Mike's age is " + Mike.age);//Mike's age is 22
//老代码仍然能够正常跑!!!
}
}
参考文档
- JAVASCRIPT.INFO,Property getters and setters,https://zh.javascript.info/promise-basics