JavaScript: js可枚举属性和不可枚举属性
我们一般认为,可以被for in遍历出来的属性就是可枚举属性,否则就是不可枚举属性。对象的属性的可枚举性和不可枚举性是由属性的enumerable值决定的,true为可枚举,false为不可枚举。
js中基本包装类型的原型属性是不可枚举的,如Object, Array, Number,Function,Date等,而自己定义的属性一般可枚举,举例:
var fun = new Function() for (var key in fun) { console.log(key); // 什么也没打印出来 } var num = new Number() for(var key in num) { console.log(key) // 什么也没打印出来 } var info = { name: '张三', age: 18 } for(var key in info) { console.log(key) // name,age }
属性的可枚举或者不可枚举影响以下几个操作的结果for...in、Object.keys()、JSON.stringify()和Object.assign() 。举例:
function Person() { this.name = '张三' } Person.prototype.age = 18 var p = new Person() Object.defineProperty(p, 'sex', { value: '男', enumerable: false }) // for in for (var key in p) { console.log(key) // name,age } // Object.keys() Object.keys(p).map(key => { console.log(key) // name }) // JSON.stringify() console.log(JSON.stringify(p)) // {"name":"张三"} // Object.assign() console.log(Object.assign({},p)) // {name: "张三"}
由上可以看出:
1、for in 遍历对象的每一个可枚举属性,包括原型链上的可枚举属性
2、Object.keys() 只能遍历自己对象上的可枚举属性,不能遍历自己原型上的可枚举属性
3、JSON.stringify() 只能读取对象本身的可枚举属性,并序列化为JSON对象
4、Object.assign() 会忽略enumerable为false的属性,只合并对象自身的可枚举的属性
Object.getOwnPropertyNames()可以读取对象本身的所有属性,不管enumerable的值
function Person() { this.name = '张三' } Person.prototype.age = 18 var p = new Person() Object.defineProperty(p, 'sex', { value: '男', enumerable: false }) Object.getOwnPropertyNames(p).forEach(key=>{ console.log(key) // name,sex })
可以通过propertyIsEnumerable方法判断该属性是否可枚举
function Person() { this.name = '张三' } Person.prototype.age = 18 var p = new Person() Object.defineProperty(p, 'sex', { value: '男', enumerable: false }) console.log(p.propertyIsEnumerable('name')) // true console.log(p.propertyIsEnumerable('age')) // false console.log(p.propertyIsEnumerable('sex')) // false