interview
frontend-classic
什么是JS对象的可枚举性(enumerable)?

前端经典面试题合集, 什么是 JS 对象的可枚举性enumerable?

前端经典面试题合集, 什么是 JS 对象的可枚举性enumerable?

QA

Step 1

Q:: 什么是 JS 对象的可枚举性(enumerable)?

A:: 在 JavaScript 中,对象的属性有一个称为 'enumerable' 的内部属性,它决定了属性是否可以在 for...in 循环或 Object.keys() 等方法中被枚举。默认情况下,通过直接在对象上定义的属性是可枚举的,而通过 Object.defineProperty() 定义的属性默认是不可枚举的。

Step 2

Q:: 如何检查一个属性是否是可枚举的?

A:: 可以使用对象的 propertyIsEnumerable 方法来检查某个属性是否是可枚举的。例如:object.propertyIsEnumerable('propertyName')

Step 3

Q:: 如何设置对象属性的可枚举性?

A:: 可以使用 Object.defineProperty() 方法来设置属性的可枚举性。通过传递一个描述符对象,可以将 enumerable 属性设置为 true 或 false。例如:Object.defineProperty(object, 'propertyName', { enumerable: false })

Step 4

Q:: for...in 循环和 Object.keys() 有什么区别?

A:: for...in 循环会枚举对象自身的和继承的可枚举属性,包括原型链上的属性。而 Object.keys() 方法只会返回对象自身的可枚举属性的键名,不包括继承的属性。

Step 5

Q:: 哪些 JavaScript 内置对象属性是不可枚举的?

A:: 许多 JavaScript 内置对象的属性是不可枚举的,例如 Array.prototype.length、Object.prototype.toString 等。这些属性通常通过 Object.defineProperty() 定义,以确保它们在枚举对象属性时不会被意外列出。

用途

了解对象的可枚举性对于开发人员控制属性的可见性和枚举性非常重要。在实际生产环境中,开发者可能需要定义一些对象属性,但不希望这些属性被枚举出来,例如内部计数器、标志位等。通过控制属性的可枚举性,可以更好地保护数据和优化性能。\n

相关问题

🦆
JavaScript 中属性描述符是什么?

属性描述符是一个对象,用来描述属性的特性。它可以包含值(value)、可写性(writable)、可枚举性(enumerable)、可配置性(configurable)等属性。例如:{ value: 42, writable: true, enumerable: false, configurable: true }

🦆
什么是对象的原型链?

对象的原型链是一个对象及其原型的链条,每个对象都有一个原型对象,通过原型对象可以访问继承的属性和方法。当访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript 引擎会沿着原型链向上查找,直到找到该属性或到达链的末端。

🦆
如何在 JavaScript 中创建一个不可变对象?

可以使用 Object.freeze() 方法来创建一个不可变对象。这个方法会冻结对象,阻止对其现有属性的修改(包括值、可写性、可配置性),并阻止添加新属性。例如:const obj = Object.freeze({ prop: 42 });

🦆
什么是 JavaScript 中的 getter 和 setter?

getter 和 setter 是一种在访问和设置对象属性时执行特定逻辑的方法。使用 Object.defineProperty() 或 ES6 的对象字面量语法,可以定义 getter 和 setter。getter 在读取属性值时调用,setter 在写入属性值时调用。例如:Object.defineProperty(obj, 'propertyName', { get: function() { return 'value'; }, set: function(newValue) { /* set value logic */ } });

🦆
Object.defineProperty 和 Object.defineProperties 有什么区别?

Object.defineProperty() 用于定义单个属性,而 Object.defineProperties() 则允许同时定义多个属性。前者接受三个参数(对象、属性名、属性描述符),而后者接受两个参数(对象、属性描述符对象)。例如:Object.defineProperties(obj, { prop1: { value: 42 }, prop2: { value: 'hello' } })