什么是getter 和 setter ?
getter: 读取对象属性时将被调用的函数。
setter:设置对象属性时被调用的函数。
有以下4中方式可以使用 setter 和 getter:
1. 对象初始化器set/get 关键字
使用get/set关键字为属性添加一个函数,函数名即为属性名,get函数不传参,set函数传入的参数为设置对象的新值。
例如:
var person = {
_name: '',
get name() { return this._name },
set name(newName) { this._name = newName }
}
// 测试
person.name // ''
person.name = 'john' // 'john', 此时 person._name 也变成了 'john'
2. Object.defineProperty()
Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。
语法:
Object.defineProperty(obj, prop, descriptor)
参数:
obj:
需要定义属性的对象。
prop:
需被定义或修改的属性名。
descriptor:
需被定义或修改的属性的描述符。
var person = {}
var name = ''
Object.defineProperty(person, 'name', {
configurable: true,
enumerable: true,
get: function() {
return name
},
set: function(newName) {
name = newName
}
})
// 测试
person.name // undefind
person.name = 'john' // 'john',此时全局的 name 也变成了 'john'
3. Object.defineProperties()
在一个对象上添加或修改一个或多个自由属性。
用法类似Object.defineProperty()
语法
Object.defineProperties(obj, props)
参数
obj:
将要被添加属性或修改属性的对象
props: 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
var obj = {a:1,b:"string"};
Object.defineProperties(obj,{
"A":{
get:function(){return this.a+1;},
set:function(val){this.a = val;}
},
"B":{
get:function(){return this.b+2;},
set:function(val){this.b = val}
}
});
//测试
obj.A; //2
obj.B; // "string2"
obj.A = 3;
obj.B = "hello";
obj.A; // 4
obj.B; // "hello2"
4. Object.create()
Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。即提供新创建的对象的__proto__。
语法
Object.create(proto, [ propertiesObject ])
参数
proto:新创建对象的原型对象
propertiesObject:可选。新创建对象的可枚举属性对象的属性描述符以及相应的属性名称,这些属性对应Object.defineProperties()的第二个参数。
var o = null;
o = Object.create(Object.prototype,//指定原型为 Object.prototype
{
bar:{
get :function(){
return 10;
},
set : function (val) {
console.log("Setting `o.bar` to ",val);
}
}
}//第二个参数
);
//测试
o.bar; //10
o.bar = 12; // 控制台打印出:"Setting `o.bar` to 12"
如果你希望对象属性值只能读取不能被修改,那么可以不设置set函数。
目前流行的框架Vue的响应式系统就是利用Object.defineProperty() 设置getter/setter来追踪数据变化,从而导致视图更新。