js中的枚举和不可枚举

本文详细介绍了JavaScript中的枚举概念,包括基本数据类型的枚举限制,以及如何使用for...in循环、Object.keys()方法和JSON.stringify()来枚举不同类型的属性。

枚举是什么???

枚举是指对象中的属性是否可以遍历出来,再简单点说就是属性是否可以以列举出来。

在js中基本的数据类型是不能被枚举的。例如Object、Array等。

枚举方法的区别

1.for…in循环可以枚举(遍历)出对象本身具有的属性,通过Object.defineProperty()方法加的可枚举属性,或者通过原型对象绑定的可以枚举属性。
function enumer() {
    this.a = '我是对象本身就有的属性';
}
enumer.prototype.b = '我是通过原型对象挂载的属性';
let fn = new enumer();
Object.defineProperty(fn, 'c', {
    value: '我是通过Object.defineProperty方法添加的可枚举属性',
    enumerable: true  // 是否可以枚举
});
for(let item in fn) {
    console.log(item);
}
/*输出*/
// a
// b
// c
2.Object.keys()方法可以枚举对象本身的属性和通过Object.defineProperty()添加的可枚举属性
function enumer() {
    this.a = '我是对象本身就有的属性';
}
enumer.prototype.b = '我是通过原型对象挂载的属性';
let fn = new enumer();
Object.defineProperty(fn, 'c', {
    value: '我是通过Object.defineProperty方法添加的可枚举属性',
    enumerable: true
});
console.log(Object.keys(fn));
/*输出*/
// ["a", "c"]
3.JSON.stringify()方法只能序列化本身的属性和通过Object.defineProperty()添加的可枚举属性为JSON对象
function enumer() {
    this.a = '我是对象本身就有的属性';
}
enumer.prototype.b = '我是通过原型对象挂载的属性';
let fn = new enumer();
Object.defineProperty(fn, 'c', {
    value: '我是通过Object.defineProperty方法添加的可枚举属性',
    enumerable: true
});
console.log(JSON.stringify(fn));
// {"a":"我是对象本身就有的属性","c":"我是通过Object.defineProperty方法添加的可枚举属性"}

-

<think>好的,用户想了解JavaScript中可枚举不可枚举属性的定义区别。首先我需要回忆一下相关知识,确保自己理解正确。可枚举属性是指那些可以被for...in循环遍历的属性,而不可枚举的则不行。这涉及到对象的属性描述符,尤其是enumerable标志。 接下来,我应该从基础定义入手,解释什么是可枚举属性。比如,用户可能不知道属性描述符是什么,需要简单介绍。然后,通过例子说明默认情况下哪些属性是可枚举的,比如通过字面量定义的属性,而像toString这样的内置属性通常是不可枚举的。 然后要区分两者的区别,比如遍历方式的不同,序列化时的表现,以及如何检测属性是否可枚举。这里可以提到Object.keysfor...in的区别,还有propertyIsEnumerable方法的使用。 用户提供的引用中有提到propertyIsEnumerable方法,需要正确引用。同时,注意用户提供的引用可能有重复,需要整合信息,避免重复引用。 可能用户还想知道如何设置属性的可枚举性,所以需要提到Object.defineProperty方法,并举例如何创建一个不可枚举的属性。 还要注意回答结构,按照用户的要求分点说明,保持清晰。最后生成相关问题,帮助用户深入理解,比如如何修改属性描述符或实际应用中的影响。 需要确保所有术语使用正确,比如属性描述符中的enumerable,而不是enumerable标志。同时检查LaTeX格式是否符合要求,比如行内公式用$...$,但这里可能用不上数学公式,但需要确认是否有需要的地方。 最后,确保回答符合用户的中文要求,引用标记正确添加到相关段落末尾,比如引用[^1]、[^3]等。检查是否有遗漏的信息点,比如JSON.stringify是否受可枚举性影响,这也是区别的一部分。</think>### JavaScript可枚举不可枚举属性解析 #### 1. 属性定义 - **可枚举属性**:通过常规赋值方式定义的属性默认可枚举,例如: ```javascript let obj = { name: "Alice" }; // name属性默认enumerable为true ``` - **不可枚举属性**:通过$Object.defineProperty()$显式设置$enumerable: false$的属性,例如: ```javascript Object.defineProperty(obj, 'id', { value: 123, enumerable: false }); ``` #### 2. 核心区别 | 特性 | 可枚举属性 | 不可枚举属性 | |---------------------|--------------------------|--------------------------| | **for...in遍历** | 可见 | 不可见 | | **Object.keys()** | 包含 | 不包含 | | **JSON.stringify()** | 序列化 | 忽略 | | **默认创建方式** | 字面量/点运算符赋值 | 需显式定义 | #### 3. 检测方法 使用$propertyIsEnumerable()$判断属性可枚举性: ```javascript console.log(obj.propertyIsEnumerable('name')); // true console.log(obj.propertyIsEnumerable('id')); // false [^4][^5] ``` #### 4. 特殊案例 内置对象属性如$toString$默认不可枚举: ```javascript // 原型链属性不可枚举 console.log(Object.prototype.propertyIsEnumerable('toString')); // false ``` #### 5. 操作差异对比 ```javascript let obj = { a: 1 }; Object.defineProperty(obj, 'b', { value: 2, enumerable: false }); // 遍历测试 for (let key in obj) console.log(key); // 输出: "a" console.log(Object.keys(obj)); // 输出: ["a"] console.log(JSON.stringify(obj)); // 输出: {"a":1} ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值