一、枚举是什么
- 枚举指对象的属性是否可以遍历出来,简单点说就是是否可以被列举出来。可枚举性决定了这个属性能否被for…in查找遍历到。
- js中基本包装类型的原型属性是不可枚举的,比如:
基本包装类型:Boolean,Number和String,就是即是基本类型,也是引用类型。基本包装类型还可以像引用类型一样通过对象的方法访问它自带的一些方法,但是不能像引用类型那样自定义方法。
var num = new Number();
for(var pro in num) {
console.log("num." + pro + " = " + num[pro]);
}
结果为空,因为Number中内置的属性是不可枚举的;
- 判断一个属性是否可枚举,用
Object.propertyIsEnumerable()
来判断,但需要注意的一点是如果需要判断的属性在object的原型链上,不管它是否可枚举,Object.propertyIsEnumerable()
都会返回false
propertyIsEnumerable()
方法返回一个布尔值,表示指定的属性是否可枚举。但是在原型链上propertyIsEnumerable不被考虑
hasOwnProperty()
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性
二、枚举性的作用
- 属性的枚举性会影响以下三个函数的结果:
for…in
Object.keys()
JSON.stringify()
举例:
function enumer(){
this.a = '我是对象本身就有的属性'
}
enumer.prototype.b = '我是通过对象原型挂载的属性'
let fn = new enumer()
Object.defineProperty(fn,'c',{
value:'我是通过Object.defineProperty方法添加的可枚举属性',
enumerable:true
})
1、 .for…in循环可以枚举(遍历)出对象本身具有的属性,通过Object.defineProperty()方法加的可枚举属性,或者通过原型对象绑定的可以枚举属性。
for(let pro in fn){
console.log(pro)
}
/*输出*/
//a
//b
//c
2、 Object.keys()方法可以枚举实例对象本身的属性和通过Object.defineProperty()添加的可枚举属性,即不会枚举原型链上的属性
console.log(Object.keys(fn))
/*输出*/
//['a','c']
**Object.keys()**
方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用for...in
循环遍历该对象时返回的顺序一致 。
例子:
// simple array
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']
// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']
var anObj = { '100': 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']
var anObj = { 'aa': 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', 'aa']
var anObj = { 'aa': 'a', 2: 'b', 'bbb': 'c' };
console.log(Object.keys(anObj)); // console: ['2', 'aa', 'bbb']
// getFoo is a property which isn't enumerable
var myObj = Object.create({}, {
getFoo: {
value: function () { return this.foo; }
}
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']
如果你想获取一个对象的所有属性,,甚至包括不可枚举的,请查看Object.getOwnPropertyNames
。
3、JSON.stringify()方法只能序列化实例对象本身的属性和通过Object.defineProperty()添加的可枚举属性为JSON对象,即不会序化原型链上的属性
console.log(JSON.stringify(fn))
//{"a":"我是对象本身就有的属性","c":"我是通过Object.defineProperty方法添加的可枚举属性"}
为什么要加上实例二字呢?请看下面
image
网友评论