JS获取对象属性的各种方式和区别(自身/原型属性、可枚举/不可枚举)

对象的属性有自身属性和原型属性之分,自身属性是对象自己的属性,原型属性是存在于原型链上的属性。

可以用Object.prototype.hasOwnProperty()判断是自身属性还是原型属性。(in操作符只可以判断对象是否有某个属性,不能判断是自身的,还是原型上的)

对象属性也有可枚举和不可枚举之分,可枚举属性的属性描述符enumerable为true,不可枚举属性的为false。

原生对象的大多数属性都是不可枚举的,比如数组和字符串的length,对象原型上的一些方法和属性,比如toString、constructor、hasOwnProperty等等

下面看下都有哪些方式可以获取对象的属性

Object.keys()

返回自身的可枚举属性组成的数组 (不包含symbol)

Object.getOwnPropertyNames()

返回所有的自身属性 组成的数组 (不包含symbol)

Object.getOwnPropertySymbols()

返回自身所有的Symbol属性组成的数组

for…in

遍历对象的所有可枚举属性

区别

可枚举可枚举和不可枚举
仅自身属性Object.keysObject.getOwnPropertyNames
自身和原型属性for…in

没有原生的方法可以获取对象上所有的属性,包含自身和原型、可枚举和不可枚举,需要自己实现,示例如下:

function getAllkeys (obj) {
  const keys = []
  let temp = obj
  while (temp) {
      keys.push.apply(keys, Object.getOwnPropertyNames(temp))
      keys.push.apply(keys, Object.getOwnPropertySymbols(temp))
      temp = Object.getPrototypeOf(temp)
  }
  return keys
}

for…of 和 for…in的区别

for let i in obj 是以任意顺序遍历对象的可枚举属性,i是key

for let value of iterable 是按顺序迭代一个可迭代对象,i是值

iterable可迭代对象包括:Array、Map、Set、String、TypedArray、arguments

<think>好的,我现在需要回答用户关于JavaScript对象不可枚举属性的问题。用户想知道哪些属性不可枚举的,以及不可枚举的具体含义。首先,我要回忆一下JavaScript对象属性的相关知识,特别是关于属性描述符的部分。 我记得对象的每个属性都有一个属性描述符,其中enumerable决定属性是否可枚举。默认情况下,通过对象字面量或赋值添加的属性可枚举的,比如`obj.a = 1`中的a属性。而通过`Object.defineProperty`定义的属性如果不指定enumerable,默认为false,也就是不可枚举。这一点需要确认是否正确,可能需要查阅参考资料。 接下来,用户问哪些属性不可枚举的。常见的内置对象不可枚举属性有哪些呢?比如,数组的length属性不可枚举的,Object.prototype上的方法如toString、hasOwnProperty也是不可枚举的。此外,通过Object.defineProperty显式设置为不可枚举属性,比如在示例中的obj.b。这些例子是否准确?需要核对引用内容。 然后,不可枚举的含义是什么?即这些属性不会被for...in循环遍历到,也不会被Object.keys()获取到。但是,可以通过Object.getOwnPropertyNames()获取所有自身属性,包括不可枚举的。JSON.stringify()也不会序列化不可枚举属性。这些要点是否都正确?需要参考提供的引用资料,尤其是引用1、2、3、4中的内容。 现在需要组织回答结构。首先解释不可枚举属性的定义,由enumerable标志控制。然后列举常见的不可枚举属性,如内置对象的length、原型方法,以及通过defineProperty定义的属性。接着说明不可枚举的影响,如遍历方法序列化。最后给出检测方法,比如propertyIsEnumerable方法getOwnPropertyDescriptor。 还要确保使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$。不过这个问题可能涉及较少的数学公式,但如果有提到算法或数学相关的内容,可能需要应用。不过当前主题主要是对象属性,可能用不上太多数学表达式,但需注意用户提到的所有行内数学表达式必须用$包裹,比如如果有变量的话。 然后生成相关问题,可能涉及如何检测不可枚举属性、如何定义、应用场景等。需要确保问题相关且符合用户示例中的结构。 最后检查引用是否正确,每个引用标识对应正确的来源。用户提供的引用都是关于可枚举性的,所以需要正确引用到对应的点,比如引用[1]、[2]、[3]、[4]。 可能的遗漏点:是否有其他内置对象不可枚举属性,比如函数的arguments、caller等属性是否不可枚举?或者ES6新增的Symbol属性是否涉及?不过用户的问题可能更基础,不需要深入这些细节,但需要确认常见例子是否正确。 总结步骤: 1. 定义不可枚举属性,由enumerable决定。 2. 列举不可枚举属性的例子:内置属性如length、原型方法,自定义通过defineProperty设置的。 3. 不可枚举的影响:遍历方法不包含,序列化忽略。 4. 检测方法。 5. 相关问题生成。 现在按照这个结构整理答案,确保引用正确,语法正确,使用中文,符合用户要求的格式。</think>### JavaScript对象不可枚举属性 #### 不可枚举属性的定义 在JavaScript中,对象的每个属性都有一个**属性描述符**,其中的`enumerable`标志决定了属性是否可枚举。若`enumerable: false`,则该属性不可枚举属性不可枚举属性不会被`for...in`循环遍历到,也不会被`Object.keys()`或`JSON.stringify()`包含[^1][^2][^4]。 #### 常见的不可枚举属性 1. **内置对象的默认属性** - 数组的`length`属性:`Object.getOwnPropertyDescriptor([], "length").enumerable` 返回`false`。 - `Object.prototype`上的方法如`toString`、`hasOwnProperty`: ```javascript Object.getOwnPropertyDescriptor(Object.prototype, "toString").enumerable; // false ``` 2. **通过`Object.defineProperty`显式定义的不可枚举属性** ```javascript const obj = {}; Object.defineProperty(obj, "b", { value: 2, enumerable: false }); console.log(obj.propertyIsEnumerable("b")); // false ``` #### 不可枚举属性的影响 1. **遍历方法忽略** - `for...in`循环不会遍历不可枚举属性[^1]。 - `Object.keys()`仅返回可枚举的自身属性[^3]。 - 若要获取所有自身属性(包括不可枚举),需使用`Object.getOwnPropertyNames()`[^4]。 2. **序列化忽略** `JSON.stringify()`不会序列化不可枚举属性。 #### 检测不可枚举属性 1. **`propertyIsEnumerable`方法** ```javascript const arr = [1, 2]; console.log(arr.propertyIsEnumerable("length")); // false ``` 2. **查看属性描述符** ```javascript const descriptor = Object.getOwnPropertyDescriptor(obj, "b"); console.log(descriptor.enumerable); // false ``` #### 示例代码 ```javascript const obj = { a: 1 }; Object.defineProperty(obj, "b", { value: 2, enumerable: false }); console.log(Object.keys(obj)); // ["a"] console.log(Object.getOwnPropertyNames(obj)); // ["a", "b"] ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值