Object.defineProperty(obj, prop, descriptor)
obj
需要定义属性的对象。
prop
需被定义或修改的属性名。
descriptor
需被定义或修改的属性的描述符。
var o = {};
o.a = 1; // 等同于 : Object.defineProperty(o, "a", { value : 1, writable : true, configurable : true, enumerable : true });
// 另一方面,
Object.defineProperty(o, "a", { value : 1 }); // 等同于 : Object.defineProperty(o, "a", { value : 1, writable : false, configurable : false, enumerable : false });
configurable
: 仅当该属性的 configurable 为 true
时,该属性才能够被改变,也能够被删除。默认为 false
enumerable
: 仅当该属性的 enumerable 为 true
时,该属性才能够出现在对象的枚举属性中。默认为 false
value
: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
writable
: 仅当仅当该属性的writable为 true
时,该属性才能被赋值运算符改变。默认为 false
get
: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined
。该方法返回值被用作属性值。undefined
set
: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined
。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined
。
特殊:1.当configurable为false时,writable只能从true改为false。
2.在 descriptor 中不能同时设置访问器(get 和 set)和 wriable 或 value,否则会错,就是说想用 get 和 set,就不能用 writable 或 value 中的任何一个。
get和set是我们今天要重点讨论的两个方法,先看一下他们的简单实例:
虽然我将a.b的值设置成了1,但是因为我在get方法中始终返回了2,所以a.b的值一直是2。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> <script> var book={ _year: 2004, edition:1 }; Object.defineProperty(book,"year",{ get: function(){ return this._year; }, set : function(newValue){ if (newValue > 2004){ this._year = newValue; this.edition = newValue; } } }); console.log(book.year) //2004 book.year =2005; console.log(book.year) //2005 console.log(book); //{_year: 2005, edition: 2005} </script> </body> </html>
那么,这就好玩儿了:我们可以在页面监听某个变量,当变量发生变化的时候,我们就更新对应的视图。由数据来驱动视图的更新,是不是很熟悉?是的,vue .js的核心思想就是这个。我们写个小例子:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> <div id="test">这是一个测试</div> <script> var view = document.getElementById("test"); var data = {}; var i=0; Object.defineProperty(data, "b", { set: function(newValue) { //当data.b的值改变的时候更新#test的视图 view.textContent=newValue; }, get: function() { } }); setInterval(function(){ i++; data["b"] = "data.b的值更新了,我要更新视图"+i; },1000); </script> </body> </html>
视图的变化过程:
最开始的视图
1秒后的视图