1.定义
- Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
- 通俗的讲,Object.defineProperty()方法的最基本功能就是定义和改变新属性,在此基础上还可以完成属性值的存取权限定义等复杂功能。
- 基本语法如下
Object.defineProperty(obj, 'key', {
enumerable: false,
configurable: false,
writable: false,
value: "55252",
get () {},
set () {}
});
2.value
3.writable
- 当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
- 当writable属性设置为false时,该属性被称为“不可写”。它不能被重新分配。
var o = {};
Object.defineProperty(o, 'b', {
value: 2,
writable: false
});
o.b = 3; // throws TypeError: "b" is read-only
4.enumerable
- 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。
- enumerable定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。
var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable:true });
Object.defineProperty(o, "b", { value : 2, enumerable:false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则这个属性的enumerable为true
for (var i in o) {
console.log(i);
}
// 打印 'a' 和 'd' (in undefined order)
Object.keys(o); // ["a", "d"]
o.propertyIsEnumerable('a'); // true
o.propertyIsEnumerable('b'); // false
o.propertyIsEnumerable('c'); // false
5.configurable
- 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
- configurable特性表示对象的属性是否可以被删除,以及除writable特性外的其他特性是否可以被修改。
- 通俗的讲,就是描述了可不可以通过Object.definePropery来改写。
var o = {};
Object.defineProperty(o, "a", { get : function(){return 1;},
configurable : false } );
// throws a TypeError
Object.defineProperty(o, "a", {configurable : true});
// throws a TypeError
Object.defineProperty(o, "a", {enumerable : true});
// throws a TypeError (set was undefined previously)
Object.defineProperty(o, "a", {set : function(){}});
// throws a TypeError (even though the new get does exactly the same thing)
Object.defineProperty(o, "a", {get : function(){return 1;}});
// throws a TypeError
Object.defineProperty(o, "a", {value : 12});
console.log(o.a); // logs 1
delete o.a; // Nothing happens
console.log(o.a); // logs 1
6.get和set
- get一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
- set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。
- get 函数能监测到该对象属性被获取,并且get函数就是获取后的回调。set函数能监测到该对象属性被改变,并且set函数就是改变后的回调。
- vue的实时数据更新就是利用的get和set,下面是一个简单的demo。
//视图控制器
var userInfo = {};
Object.defineProperty(userInfo, "nickName", {
get: function(){
console.log('nickName get');
return document.getElementById('nickName').innerHTML;
},
set: function(nick){
console.log('nickName set');
document.getElementById('nickName').innerHTML = nick;
}
});
Object.defineProperty(userInfo, "introduce", {
get: function(){
console.log('introduce get');
return document.getElementById('introduce').innerHTML;
},
set: function(introduce){
console.log('introduce set');
document.getElementById('introduce').innerHTML = introduce;
}
})
function Archiver() {
var temperature = null;
var archive = [];
Object.defineProperty(this, 'temperature', {
get: function() {
console.log('get!');
return temperature;
},
set: function(value) {
temperature = value;
archive.push({ val: temperature });
}
});
this.getArchive = function() { return archive; };
}
var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
7.总结
- vue的双向数据绑定原理:当通过js改变对象的某一属性值时,会触发set函数,然后将dom中对应的文本内容替换。当获取某一属性值时,get函数会自动获取dom的内容。从而达到实时更新。