前言
对象属性有2种类型:
- 数据属性。基本上使用过的属性都属于数据属性。
- 访问器属性(accessor property)。本质上是用于获取和设置值的函数。
访问器属性由 “getter
” 和 “setter
” 方法表示。
在 JavaScript 中,getter
(获取器)和setter
(设置器)是用于定义对象属性的访问和修改行为的特殊方法。
getter(获取器)
getter
用于获取属性的值,当访问该属性时会自动调用getter
方法。
getter
具有以下特点:
- 定义方式:使用
get
关键字来定义。 - 自动调用:当访问定义了
getter
的属性时,会自动调用对应的get
方法来获取属性值。 - 计算属性:可以基于其他属性或进行一些计算来返回属性值,而不仅仅是直接返回存储的值。
示例:
let person = {
firstName: '张',
lastName: '三',
get fullName() {
return this.firstName + this.lastName;
}
};
// 以属性的方式正常读取fullName:getter 在幕后运行
console.log(person.fullName);
在示例中,fullName
是使用 getter
定义的属性,它通过计算 firstName
和 lastName
的值来返回结果。
当读取 person.fullName
时,getter
起作用。
使用get语法时应注意:
- 可以使用数值或字符串作为标识。
- 必须不带参数。示例中的
fullname()
不能带参数。 - 它不能与另一个
get
或具有相同属性的数据条目同时出现在一个对象字面量中(不允许使用{ get x() { }, get x() { } }
和{ x: ..., get x() { } })
。
使用delete
操作符删除 getter
:
delete person.fullName
setter(设置器)
setter
用于设置属性的值,当尝试为该属性赋值时会自动调用setter
方法。
setter
具有以下特点:
- 定义方式:使用
set
关键字来定义。 - 自动触发:当尝试为定义了
setter
的属性赋值时,会自动调用对应的set
方法。
示例:
let person = {
_name: '张三',
set name(newValue) {
if (typeof newValue !== 'tring') {
console.error('名字必须是字符串');
return;
}
this._name = newValue;
}
};
// 以属性赋值的方式给name赋值:setter 在幕后运行
person.name = '李四';
console.log(person._name); // 李四
person.name = 123; // Error, 输出: 名字必须是字符串
在示例中,为 name
属性定义了 setter
方法,在赋值时进行了类型检查。
setter
提供了一种在属性赋值时进行控制和处理的机制,有助于提高代码的健壮性和可维护性。
使用 set 语法时请注意:
- 它的标识符可以是数字或字符串;
- 它必须有一个明确的参数;
- 在对象字面量中,不能为一个已有真实值的变量使用
set
,也不能为一个属性设置多个set
。 ({ set x(v) { }, set x(v) { } }
和{ x: ..., set x(v) { }
} 是不允许的 )
用 delete 操作符删除 setter
delete person.name
使用 defineProperty 为当前对象定义 getter/setter
let obj = {};
Object.defineProperty(obj, "name", {
get: function() {
return this._name;
},
set: function(newValue) {
if (typeof newValue!== 'tring') {
console.error('名字必须是字符串');
return;
}
this._name = newValue;
}
});
obj.name = "张三";
console.log(obj.name);
在上述示例中,为对象 obj
的 name
属性定义了 getter
和 setter
。getter
用于获取属性值,setter
用于设置属性值,并进行了类型检查。
也可以通过obj._name
直接访问 name
。注意一个众所周知的约定:以下划线 “_” 开头的属性是内部属性,不应该从对象外部进行访问。