js中Object.defineProperty的使用方法
需要的三个参数为必填项
Object.defineProperty(obj, prop, descriptor)
obj:需要定义属性的对象
prop:需被定义或修改的属性名
descriptor:需被定义或修改的属性的描述符
descriptor可以设置的项
configurable 可配置特性总开关,一旦为false,就不能再设置他的(value,writable,configurable)
enumerable 可枚举属性设置此属性是否可以枚举,也就是可以用for语句遍历
writable 可以写特性设置此属性是不是可写
value 值属性的值
getter 设置 方法(get)读取值的时间会调用
setter 设置方法(set)设置值的时候会调用
要注意的一项配置 configurable
可以说是当前设置属性项的总开关。当 configurable 这个属性为 true 的时候表示这个属性可以从父对象中删除。当 configurable 设置为 false 的时候就会锁定这个属性,这个属性的所有项都无法被修改。通过设置 configurable 我们可以将一些属性锁定,来防止别人的修改,这是一种防御编程形式,就像语言的内置对象一样(不过 JavaScript 的内置对象都可以被随意更改)。
配置项默认值
在设置属性的descriptor时如果有没有设置的项则默认设置为false 如 configurable,enumerable,writable 这几个是有默认值的,默认为false
如下
var obj1 = {} Object.defineProperty(obj1, 'name', { value: '第一个名字' })
configurable,enumerable,writable这些值都会被设置为false,也就是说name这个属性成为只读的啦,后面就不可以修改啦
例如使用writable定义属性为只读
var obj1 = {} Object.defineProperty(obj1, 'name', { writable: false, value: '第一个名字' }) obj1.name='改掉名字'; console.log(obj1);
如上图定义的是只读属性,重新赋值后输出的还是原来的值并且name显示是灰色的表示是只读的,这个时候如果再定义一次就会报错,如下图
这是因为上面定义只读属性的时候没有设置其它几个值,它们就默认为false啦,其中有一个configurable 全局配置的开关也默认为false啦,锁定啦此属性的所有descriptor配置项,所以之后再改属性时就会出错
如果一开始定义只读的时候使用下面方法定义,把总开关定义为true,之后的代码就又可以把属性改成其它的啦
Object.defineProperty(obj1, 'name', { configurable:true, writable: false, value: '第一个名字' })
监测document.cookie
监测网页加载期间设置的cookie值
Object.defineProperty(document, 'cookie', { set:function(val1){ console.log(val1); if(!val1){ return ; } if(val1.indexOf('.309')!=-1){ debugger; } } })
重定义array.join方法
Object.defineProperty(Array.prototype, 'join', { value:function(){ var val=''; for(var i=0;i<this.length;i++){ val+=val?(arguments[0]+this[i]):this[i]; } return val; } })