Обмен технологиями

ES6 Reflect Подробное объяснение (3)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Объект Reflect, как и объект Proxy, — это новый API, предоставляемый ES6 для управления объектами. Объекты Reflect предназначены для четырех целей.

  1. Поместите некоторые методы объекта Object, которые явно являются внутренними для языка (например, Object.defineProperty), в объект Reflect. На этом этапе некоторые методы развертываются как на объектах Object, так и на объектах Reflect, а новые методы в будущем будут развернуты только на объектах Reflect. Другими словами, внутренние методы языка можно получить из объекта Reflect.
  2. Измените возвращаемые результаты некоторых методов Object, чтобы сделать их более разумными. Например, Object.defineProperty(obj, name, desc) выдаст ошибку, если свойство не может быть определено, а Reflect.defineProperty(obj, name, desc) вернет false.
// 老写法
try {
  Object.defineProperty(target, property, attributes);
  // success
} catch (e) {
  // failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
  // success
} else {
  // failure
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  1. Пусть операции с объектами станут функциональным поведением. Некоторые операции над объектами являются обязательными, например, name в obj и delete obj[name], но Reflect.has(obj, name) и Reflect.deleteProperty(obj, name) превращают их в функциональное поведение.
// 老写法
'assign' in Object // true
// 新写法
Reflect.has(Object, 'assign') // true
  • 1
  • 2
  • 3
  • 4
  1. Методы объекта Reflect взаимно однозначно соответствуют методам объекта Proxy. Если это метод объекта Proxy, соответствующий метод можно найти в объекте Reflect. Это позволяет объекту Proxy легко вызывать соответствующий метод Reflect, чтобы завершить поведение по умолчанию и служить основой для изменения поведения. Другими словами, независимо от того, как Proxy изменяет поведение по умолчанию, вы всегда можете получить поведение по умолчанию в Reflect.
Proxy(target, {
  set: function(target, name, value, receiver) {
    var success = Reflect.set(target, name, value, receiver);
    if (success) {
      console.log('property ' + name + ' on ' + target + ' set to ' + value);
    }
    return success;
  }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Метод Proxy перехватывает поведение назначения атрибутов целевого объекта. Он использует метод Reflect.set для присвоения значений свойствам объекта, гарантируя завершение исходного поведения, а затем развертывает дополнительную функциональность.

Часто используемые методы:

Reflect.get(target, propertyKey[, получатель]): Получите свойства объекта.
Reflect.set(target, propertyKey, value[, получатель]): установите свойства объекта.
Reflect.has(target, propertyKey): определяет, существует ли свойство у объекта.
Reflect.deleteProperty(target, propertyKey): Удалить свойства объекта.
Reflect.ownKeys(target): возвращает массив всех свойств самого объекта.
Reflect.getOwnPropertyDescriptor(target, propertyKey): Получите дескриптор свойства объекта.
Reflect.defineProperty(target, propertyKey, Attributes): Определите или измените свойства объекта.
Reflect.preventExtensions(target): запретить расширение объекта.
Reflect.isExtensible(target): определяет, является ли объект расширяемым.
Reflect.getExtension(target): получить прототип объекта.
Reflect.setPrototypeOf(target, Prototype): Установить прототип объекта.

Пример 1: Использование Reflect.get

let obj = { name: "Alice", age: 25 };
let propName = "name";

console.log(Reflect.get(obj, propName)); // 输出:Alice
console.log(Reflect.get(obj, "gender")); // 输出:undefined
  • 1
  • 2
  • 3
  • 4
  • 5

Пример 2: Использование Reflect.set

let obj = { name: "Alice" };

// 设置属性
console.log(Reflect.set(obj, "age", 30)); // 输出:true

console.log(obj); // 输出:{ name: "Alice", age: 30 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Пример 3: Использование Reflect.has

let obj = { name: "Alice" };

console.log(Reflect.has(obj, "name")); // 输出:true
console.log(Reflect.has(obj, "age"));  // 输出:false
  • 1
  • 2
  • 3
  • 4

Пример 4: Использование Reflect.deleteProperty

let obj = { name: "Alice", age: 30 };

// 删除属性
console.log(Reflect.deleteProperty(obj, "age")); // 输出:true

console.log(obj); // 输出:{ name: "Alice" }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Пример 5: Использование Reflect.ownKeys

let obj = { name: "Alice", age: 30 };

console.log(Reflect.ownKeys(obj)); // 输出:["name", "age"]
  • 1
  • 2
  • 3

Пример 6: Использование Reflect.preventExtensions

let obj = { name: "Alice" };

// 防止对象被扩展
console.log(Reflect.preventExtensions(obj)); // 输出:true

// 尝试添加新属性
console.log(Reflect.set(obj, "age", 30)); // 输出:false
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Пример 7: Использование Reflect.isExtensible

let obj = { name: "Alice" };

console.log(Reflect.isExtensible(obj)); // 输出:true
  • 1
  • 2
  • 3

Пример 8. Использование Reflect.getPrototypeOf и Reflect.setPrototypeOf

let proto = { sayHello: function() { console.log("Hello!"); }};
let obj = Object.create(proto);

console.log(Reflect.getPrototypeOf(obj) === proto); // 输出:true

// 设置新原型
let newProto = { sayGoodbye: function() { console.log("Goodbye!"); }};
Reflect.setPrototypeOf(obj, newProto);

console.log(obj.sayGoodbye); // 可以访问新原型上的方法
obj.sayGoodbye(); // 输出:Goodbye!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Объект Reflect предоставляет набор методов, соответствующих ловушкам прокси, что делает перехват операций JavaScript более интуитивным и удобным. Использование Reflect обеспечивает согласованность и ожидаемое поведение операций, особенно когда необходимо явно фиксировать условия сбоя или ошибки.