一、什么是不可枚举属性
eg:Object.prototype的如下属性都是不能通过Object.keys()或者for循环遍历打印出来的
- 给Object.prototype添加一个属性'c'
- 遍历Object.prototype的属性,并打印
Object.prototype.c = function(){
console.log('c')
}
console.log(Object.keys(Object.prototype)
for(let key in Object.prototype){
console.log(key)
}
//打印结果:c,并没有打印出toString等属性
二、不可遍历对象的特点,为什么能打印出属性'c',其它的不可以打印
- 观察属性的“描述符”对象,使用Object.getOwnPropertyDescriptor(obj,key)输出对应属性的“描述符”对象
- 分别打印出'c'和'toString'的描述符对象,发现toString的enumerable:flase
var desc = Object.getOwnPropertyDescriptor(Object.prototype,'c')
var desc2 = Object.getOwnPropertyDescriptor(Object.prototype,'toString')
/*eg:
value: ƒ () =>属性的值
configurable: true => 表示属性描述符本身是否可以被修改
enumerable: true =>可遍历的
writable: true =>可修改,重新赋值
*/
三、怎么让属性变为不可遍历属性
- 通过Object.defineProperty(obj,key,descriptorObj)的方式定义
Object.defineProperty(Object.prototype,'c',{
value:'我不是Function',
configurable:true,
enumerable:false,
writable:true
})
console.log(Object.keys(Object.prototype)) //结果为[]
2.如果将writable:false,表示属性的值不可以被修改
Object.defineProperty(Object.prototype,'c',{
value:'我不是Function',
configurable:true,
enumerable:true,
writable:false
})
Object.prototype.c = 'hello'
console.log(Object.prototype.c) //结果为依然为 “我不是Function”
3.如果将configurable:false,表示该属性的描述符对象不可以被修改
Object.defineProperty(Object.prototype,'c',{
value:'我不是Function',
configurable:false,
enumerable:true,
writable:true
})
//再次修改C的属性描述符对象
Object.defineProperty(Object.prototype,'c',{
value:'我是修改后的C',
configurable:true,
enumerable:true,
writable:true
})
console.log(Object.prototype.c) //报错:Cannot redefine property
报错:
四、修改自带的不可遍历的属性(toString)
- 打印toString的描述符对象,发现它的描述符对象是可以修改的
- 修改toString的描述符对象
var num = 222222
var desc2 = Object.getOwnPropertyDescriptor(Object.prototype,'toString')
console.log(desc2)
Object.defineProperty(Object.prototype,'toString',{
//value:'变种toString',
configurable:true,
enumerable:true, //变为可遍历的
writable:true
})
console.log(Object.keys(Object.prototype)) //['toString']
console.log(num.toString()) // '222222'