“可枚举”,即,可以被遍历或列举出来
可枚举意味着可以被遍历或列举出来。在不同的领域和上下文中,可枚举的概念有不同的应用和解释。
1、在计算机编程中,特别是JavaScript中,可枚举属性是指那些内部“可枚举”标志设置为true的属性,这些属性可以通过for...in循环进行遍历。如果一个属性的enumerable为false,那么该属性不会被包括在for...in循环中。
2、在编程中,可枚举类型是那些带有GetEnumerator方法的类型,可以是类、数组、接口等,它返回一个枚举器。
综上所述,可枚举的概念根据应用场景的不同而有所不同,但核心意义在于能够被遍历或列举出来。
可枚举性是JavaScript中属性的一种特性,决定了该属性是否能被for...in
循环、Object.keys()
方法或JSON.stringify()
方法访问到。属性的可枚举性由其enumerable
属性决定,如果设置为true
,则属性是可枚举的;如果设置为false
,则属性是不可枚举的。
一、如何判断属性是否可枚举:
使用Object.prototype.propertyIsEnumerable()
方法可以判断一个对象是否包含某个属性,并且这个属性是否可枚举。如果属性存在于对象的原型内,不管它是否可枚举都会返回false
。
对象的属性是否具有可枚举属性是由enumerable值决定;
可以通过obj.propertyIsEnumerable(prop);来判断obj对象的prop属性是否能够枚举,该方法返回的是一个布尔值,表示指定的属性是否可枚举。但是在原型链上propertyIsEnumerable不被考虑。
语法:obj.propertyIsEnumerable(prop)
描述:每个对象都有一个propertyIsEnumerable方法。此方法可以确定对象中指定的属性是否可枚举,返回一个布尔值。但该方法对通过原型链继承的属性无效(原型链继承的属性是否可枚举不能用该方法来判断)。
注意:判断一个属性是否可枚举,用
Object.propertyIsEnumerable()
来判断,但需要注意的一点是如果需要判断的属性在object的原型链上,不管它是否可枚举,Object.propertyIsEnumerable()
都会返回false
延伸:hasOwnProperty()
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性案例:用户自定义对象和引擎内置对象的区别
Math.propertyIsEnumerable('random'); // 返回 false Object.propertyIsEnumerable('constructor'); // 返回 false var num = new Number(); for(var pro in num) { console.log("num." + pro + " = " + num[pro]); }//输出空
这说明了开发者自定义的属性在一般情况下时可以枚举的,但是内置的对象Math和基本包装类型里的属性是不可枚举的,如Object, Array, Number等;其实,propertyIsEnumerable方法只对对象自身的属性(对象自身添加的、构造函数实例化的)有效,对原型上的、继承来的属性都无效。
二、如何设置可枚举属性(enumerable)
使用Object.defineProperty()或 Object.defineProperties()方法设置属性对象的enumerable属性为true
即可。
■ 参考:JS中的可枚举属性与不可枚举属性
var person = {
name:'xiao',
age: '18',
sex: 'boy'
}
Object.defineProperty(person,'age',{
enumerable:true,//可以被枚举
});
Object.defineProperty(person,'sex',{
enumerable:false,//不可以被枚举
})
for(var k in person){
console.log(person[k])//a,可以被枚举
}
//18
//xiao
Object.defineProperty(obj, prop, descriptor)方法有三那个参数
第一个:目标对象;第二个:目标属性,字符串;第三个:对目标属性的行为,放在对象里
enumerable为true时表示可枚举,enumerable为false表示不可枚举;
开发者自己定义的对象person中的所有属性默认都是可枚举的;
如何查看ES5标准下的属性的缩微小对象?可以使用
Object.getOwnPropertyDescriptor(obj, prop)
方法获取属性的描述对象,从而判断属性是否可枚举。
番外:基本包装类型和引用类型的原型属性的可枚举性
★基本包装类型的原型属性(如String, Number, Boolean等)可以枚举。
在JavaScript中,对象的属性是否可以被枚举,即是否可以通过for...in
循环或其他遍历方法被遍历到,主要取决于该属性的可枚举性。基本包装类型的原型属性,如果被定义为可枚举,那么它们就可以被遍历。例如,通过Object.keys()
方法或JSON.stringify()
方法,只能返回和序列化对象本身的可枚举属性。这意味着,如果基本包装类型的原型属性被设置为可枚举,那么它们将能够被这些方法检测到并处理。| JS中的枚举和不可枚举 - 简书
然而,需要注意的是,不是所有的属性都是可枚举的。有些属性可能被设置为不可枚举,这意味着它们不会被for...in
循环或其他遍历方法遍历到。这种设置通常用于隐藏某些内部属性或方法,以避免它们被意外地访问或修改。
总的来说,基本包装类型的原型属性的可枚举性取决于它们的定义。如果这些属性被设置为可枚举,那么它们就可以被遍历和处理。
★引用类型的原型属性(如Object, Array等)通常被设置为不可枚举,因此,不能通过for...in
循环访问到。
在编程中,引用类型的原型属性通常指的是对象的原型上定义的属性和方法,这些属性和方法可以被所有通过该原型创建的对象继承。然而,这些原型属性并不能直接被枚举,因为它们不是直接附加到对象实例上,而是通过原型链继承得到的。因此,尝试枚举引用类型的原型属性通常没有直接的方法来实现,除非是通过遍历对象的原型链来逐一检查其属性,但这并不是一个标准的操作,且可能因语言和环境的差异而有所不同。
在JavaScript等语言中,对象的原型(prototype)属性通常用于存储共享的方法和属性,而不是用于枚举的。枚举通常指的是对一组固定的、预定义的值进行遍历或选择,而这些值通常是作为枚举类型的一部分在代码中明确声明的。因此,引用类型的原型属性并不符合枚举的定义,也无法通过标准的枚举方法来列出或访问。
此外,对于某些编程语言中的特定情况,如C#中的枚举类型,虽然可以定义枚举成员来表示选项组合,并通过位字段和位运算来处理这些选项的组合和分离,但这与引用类型的原型属性的枚举是两个不同的概念。在C#中,枚举类型的设计是为了表示一组固定的、预定义的值,而不是为了枚举对象的原型属性1。
综上所述,引用类型的原型属性通常不能被枚举,因为它们是通过原型链继承得到的,而不是直接附加到对象实例上的属性。尝试枚举这些属性通常需要遍历原型链,但这并不是一个标准的操作,且可能因语言和环境的差异而有所不同
三、枚举性的作用:
属性的可枚举性会影响for...in
循环、Object.keys()
方法和JSON.stringify()
方法的结果。例如,通过Object.defineProperty()或 Object.defineProperties()
定义的不可枚举属性不会出现在通过for...in
循环的遍历结果中。
引入可枚举性这个概念的最初目的是为了让某些属性可以规避掉for...in操作,不然内部属性和方法都会遍历到
四、获取所有属性,包括不可枚举属性:
使用Object.getOwnPropertyNames()
方法可以获取对象的所有属性,包括不可枚举的属性。这个方法返回一个包含对象自身所有属性的数组(包括不可枚举的属性),但不包括Symbol类型的属性。
■ for...in循环是 遍历对象的每一个可枚举属性,包括原型链上面的可枚举属性;
for…in循环可以枚举(遍历)出对象本身具有的属性,通过Object.defineProperty()方法加的可枚举属性,或者通过原型对象绑定的可以枚举属性。■ 而Object.keys(obj)只是遍历自身的可枚举属性,不可以遍历原型链上的可枚举属性。这是for...in 和 Object.keys()的主要区别。另外,注意它同for...in一样不能保证属性按对象原来的顺序输出。
也就是说,Object.keys()方法可以枚举实例对象本身的属性和通过Object.defineProperty()添加的可枚举属性,即不会枚举原型链上的属性
■ Object.getOwnPropertyNames()则是遍历自身所有属性(不论是否是可枚举的),不包括原型链上面的。
■ JSON.stringify()方法只能序列化实例对象本身的属性和通过Object.defineProperty()添加的可枚举属性为JSON对象,即不会序化原型链上的属性
参考:JS中的枚举和不可枚举 - 简书 | 可枚举属性、可迭代对象、迭代器(iterator)-CSDN
通过了解这些,开发者可以更好地控制对象的属性和它们的行为,特别是在需要隐藏某些属性或控制属性显示时机的情况下。例如,在创建对象时,可以通过设置属性的enumerable
值为false
来确保该属性不会被外部代码轻易访问或修改,从而增加代码的安全性和封装性。
参考资料
枚举和不可枚举 - 简书 | JS中的枚举和不可枚举 - 简书
可枚举属性、可迭代对象、迭代器(iterator)-CSDN博客
JS方法中可枚举和不可枚举什么意思-CSDN | JS中的可枚举属性与不可枚举属性-博客园