跳到主要内容

枚举属性

  • 有时候需要遍历或获取对象的所有属性。
  • Enumerable 枚举
let o = { x: 1, y: 2, z: 3 }
// 对象继承内置的方法,是不可枚举的
console.log(o.propertyIsEnumerable('toString'))
// 自己添加的属性,默认是可枚举的
console.log(o.propertyIsEnumerable('x'))
for (let p in o) {
console.log(p) // =>x,y,z,但没有toString
}
// 跳过继承属性
for (let p in o) {
if (!o.hasOwnProperty(p)) continue
}
// 跳过所有方法
for (let p in o) {
if (typeof o[p] === 'function') continue
}

取得属性名数组的 4 个函数

Object.keys() 枚举自有属性

  • 返回对象可枚举自有属性名的数组。
  • 不包含不可枚举属性、继承属性或名字是符号的属性

Object.getOwnPropertyNames()

  • 与 Object.keys()类似,
  • 但也会返回不可枚举自有属性名的数组,只要它们的名字是字符串。

Object.getOwnPropertySymbols()

  • 返回名字是符号的自有属性,无法是否可枚举。

Reflect.ownKeys()

  • 返回所有属性名,包括可枚举和不可枚举属性
  • 以及字符串属性和符号属性

Reflect

JavaScript 中的 Reflect 是一个内置对象,它提供了一组与 JavaScript 对象操作相关的方法。Reflect API 主要目的是为了标准化底层操作并为开发者提供一种更直接的方式来处理对象属性和函数调用等操作,同时它也与 Proxy 对象紧密结合,用于拦截和自定义对象的行为。

以下是 Reflect 的一些关键特性:

  1. 内省(Introspection)

    • Reflect 提供了一系列方法来检查和获取关于对象的信息,如 Reflect.has() 检查对象是否具有某个属性,Reflect.getOwnPropertyDescriptor() 获取属性描述符,Reflect.ownKeys() 列出对象的所有自身属性名(包括不可枚举的符号键)。
  2. 操作(Operations)

    • 它包含了对对象进行操作的方法,例如设置、删除属性以及调用函数等,这些操作往往与 Object 类型的某些方法相对应,但它们返回结果更加明确且总是抛出适当的错误:
      • Reflect.set(target, propertyKey, value[, receiver]) 设置对象属性值。
      • Reflect.get(target, propertyKey[, receiver]) 获取对象属性值。
      • Reflect.deleteProperty(target, propertyKey) 删除对象的属性。
      • Reflect.construct(Target, argumentsList[, newTarget]) 以指定参数列表调用构造函数,类似于 new Target(...argumentsList)
  3. 可扩展性(Extensibility)

    • Reflect API 设计的目的之一是为了更好地配合 Proxy 特性使用。通过 Proxy 创建的对象可以利用 Reflect 来实现对底层操作的捕获或修改。比如,在 Proxy 的陷阱(trap)中,常常会用到 Reflect 方法来执行默认行为或者在自定义逻辑前后执行原生操作。
  4. 类型化操作

    • Reflect 方法通常返回布尔值表示操作成功与否,并在必要时抛出异常,这使得编程更具确定性和一致性。

例如,以下是一些 Reflect 方法的简单示例:

let obj = { a: 1 }

// 使用 Reflect.has() 检查属性是否存在
console.log(Reflect.has(obj, 'a')) // true

// 使用 Reflect.set() 设置属性
Reflect.set(obj, 'b', 2)
console.log(obj) // { a: 1, b: 2 }

// 使用 Reflect.get() 获取属性
console.log(Reflect.get(obj, 'a')) // 1

// 使用 Reflect.apply() 调用函数
function sum(a, b) {
return a + b
}
console.log(Reflect.apply(sum, null, [3, 4])) // 7

总的来说,Reflect 对象增强了 JavaScript 的反射能力,使开发者能够更方便地操作和理解程序中的对象状态及其行为。