1. Object.keys和 Reflect.ownKey有什么区别?
Object.keys和 Reflect.ownKey都能遍历symbol属性,两者主要的区别在于Reflect.own-Keys()可以获得对象可枚举属性。
const symbol1=Symbol(1);
let obj1 = {name: {fist: 'shen', last: 'sun'},say:function (){},symbol1:'symbol'};
console.log(Object.keys(obj1))
console.log(Reflect.ownKeys(obj1))
// [ '1', '2', '3', '4', 'name', 'say', 'symbol1' ]
// [ '1', '2', '3', '4', 'name', 'say', 'symbol1' ]
为obj1添加一个不可枚举属性,输出两者的结果,会发现object.keys()获取不到不可枚举属性。js中的对象有可枚举属性和不可枚举属性之称,它们是由属性enumerable决定的,可枚举属性决定了能否被for...in..查到,深入了解请看第二部分。
const symbol1=Symbol(1);
let obj1 = {name: {fist: 'shen', last: 'sun'},say:function (){},symbol1:'symbol'};
Object.defineProperty(obj1, "sex", {
value: "female",
enumerable: false
});
console.log(Object.keys(obj1))
console.log(Reflect.ownKeys(obj1))
// [ '1', '2', '3', '4', 'name', 'say', 'symbol1' ]
// [ '1', '2', '3', '4', 'name', 'say', 'symbol1', 'sex' ]
2. 可枚举属性与不可枚举属性?
可枚举属性决定了这个属性能否被for...in...遍历掉,属性是否可枚举由enumerable决定。
可枚举属性还会影响JSON.stringify(),它仅能序列化当前对象内的可枚举属性(不包括方法),不包括当前对象的不可枚举属性,以及原型链上的属性。
js中基本包装类型的类型的属性都是不可枚举,Array,object,这就是为什么我们我们遍历一个Array对象或者object对象,只能打印出来我们定义的属性(对象内部定义的属性,默认是可以枚举的)。虽然for in 能够遍历原型链上面的属性,但是打印不出来concat、slice这些属性。
但是我们如果我们可以在Array原型上面添加属性,那么就可通过for...in...获取该属性,
Array.prototype.sayHello=function (){}
var a = new Array(2);
for (let i in a) {
console.log(i)
}
//sayHello
注我们可以通过Object对象的propertyIsEnumerable()方法可以判断此对象是否包含某个属性,并且这个属性是否可枚举。如果判断的属性存在于Object对象的原型内,不管它是否可枚举都会返回false。