这个东东其实没那么难,先来看看它的功能和使用方式:
Object.defineProperty(obj, prop, descriptor)
- obj: 需要定义属性的对象。
- prop: 需定义或修改的属性的名字。
descriptor: 将被定义或修改的属性的描述符。
返回值:返回传入函数的对象,即第一个参数obj。
三个参数都是必填的
关于描述符 descriptor
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。描述符必须是两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
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。
具体示例:
var o = {};// o.mm = 'lyt'Object.defineProperty(o, 'mm', { value: 'lyt', configurable: true, enumerable: true, writable: true});// 这种写法和上面的是一个意思。
如果configurable为默认值false,那么再去修改除writeable以外的属性都会抛出异常,也就是说这个属性是个总开关。
var o = {};Object.defineProperty(o, 'mm', { value: 'lyt'});Object.defineProperty(o, 'mm', { // 报错 configurable: true});
如果enumerable为默认值false,则该属性不能被for-in循环所遍历。
var o = {};Object.defineProperty(o, 'mm', { value: 'Tina', enumerable: true});Object.defineProperty(o, 'name', { value: 'lyt'});for(var key in o){ console.log(o[key]); // Tina}
如果writable为默认值false,那么属性将不可写,只能读。
var o = {};Object.defineProperty(o, 'mm', { value: 'Tina'});o.mm = 'lmm';console.log(o.mm) // Tina
关于 get 和 set 函数
通过Object.defineProperty()来设置存储描述符的时候,当对对应的数据进行读取操作的时候会触发get函数,对数据进行写入操作的时候会触发set函数,下面这个例子就会让你搞清楚它们的作用:
var o = {};Object.defineProperty(o, 'mm', { get:function (){ console.log('卢雨婷大美妞取了我的值'); return 'Tina' // 返回值即使读取的值 }, set:function (value){ // 这个参数的名字随便 console.log(`我的值被卢小妞设置成了${value}`); // 这里使用this.mm = value赋值要注意,会形成递归。 }});o.mm;o.mm = '白痴';
至于取值和赋值的时候的行为,就随需求而定了。
应用:MVVM框架的基本原理
你好: 111
222
总结:以上,你没看错,就这么简单。