一、枚举是什么?
枚举是指对象中的属性是否可以被遍历。
二、可枚举与不可枚举
JavaScript对象的属性可分为可枚举和不可枚举,它是由属性的enumeration值决定的,true为可枚举,false为不可枚举
问题1:如何设置可枚举性与不可枚举型?
Object.defineProperty()是干什么的?
给对象添加属性(指定描述符)
Object.defineProperty()如何使用?
Object.defineProperty(obj, prop, descriptor)
obj:要在其上定义属性的对象。
prop:要定义或修改的属性的名称。
descriptor:将被定义或修改的属性描述符。
对象里目前存在的属性描述符有两种主要形式:
数据描述符:具有值的属性,该值可能是可写的,也可能不是可写的。
访问描述符:由getter-setter函数对描述的属性。
描述符必须是这两种形式之一但不能同时是两者。
公共键值:数据描述符和访问描述符均具有以下可选键值(默认值是在使用Object.defineProperty()定义属性的情况下):
1.configurable:是否可以重新定义(默认为 false)
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。
2.enumerable:是否可以枚举(默认为 false)
当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。
数据描述符同时具有以下可选键值:
1.value:该属性对应的值(默认为 undefined)
可以是任何有效的 JavaScript 值(数值,对象,函数等)。
2.writable:否可以修改属性值(默认为 false)
当且仅当该属性的writable为true时,value才能被赋值运算符改变。
访问描述符同时具有以下可选键值:
1.get:回调函数,动态计算得到当前属性值(默认为 undefined)
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
2.set:回调函数,监视当前属性值的变化,更新其它相关的属性值(默认为 undefined)
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
js中原型属性一般是不可枚举的,而自定义的属性一般是可枚举的
可以通过propertylsEnumerable()方法判断该属性是否可枚举
属性的枚举性会影响以下三个函数的结果 (ES6标准入门P164)
1)for...in
可遍历原型与实例上的所有可枚举属性
2)Object.keys();
只能返回对象本身具有的可枚举属性。
3)JSON.stringify();
只能读取对象本身的可枚举属性,并序列化为JSON对象。
4)Object.getOwnPropertyNames()
遍历自身所有属性(不论是否是可枚举的),不包括原型链上面的.。
5)Object.assign() (es6新增)
自身的可枚举属性。