기술나눔

ES6 상세 설명 반영 (3)

2024-07-12

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

Reflect 객체는 Proxy 객체와 마찬가지로 객체를 조작하기 위해 ES6에서 제공하는 새로운 API입니다. Reflect 객체는 4가지 목적으로 설계되었습니다.

  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. 객체 작업을 기능적 동작으로 만듭니다. obj의 이름 및 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 객체의 메소드와 1:1로 대응됩니다. 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[, receive]): 객체의 속성을 가져옵니다.
Reflect.set(target, propertyKey, value[, receive]): 객체의 속성을 설정합니다.
Reflect.has(target, propertyKey): 객체에 속성이 존재하는지 확인합니다.
Reflect.deleteProperty(target, propertyKey): 객체의 속성을 삭제합니다.
Reflect.ownKeys(target): 객체 자체의 모든 속성 배열을 반환합니다.
Reflect.getOwnPropertyDescriptor(target, propertyKey): 객체 속성의 설명자를 가져옵니다.
Reflect.defineProperty(target, propertyKey, attribute): 객체의 속성을 정의하거나 수정합니다.
Reflect.preventExtensions(target): 객체가 확장되는 것을 방지합니다.
Reflect.isExtensible(target): 객체가 확장 가능한지 여부를 결정합니다.
Reflect.getExtension(target): 객체의 프로토타입을 가져옵니다.
Reflect.setPrototypeOf(target, 프로토타입): 객체의 프로토타입을 설정합니다.

예 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를 사용하면 특히 실패 조건이나 오류를 명시적으로 캡처해야 하는 경우 작업의 일관성과 예상되는 동작이 보장됩니다.