👋 set(), set() 트랩 호출, set() 트랩 준수사항
1. set()
- 프로퍼티를 설정하는 트랩으로
target
또는receiver
에 프로퍼티(key, value)를 설정 함 -
set()
트랩을 작성하지 않은 형태const target = {}; const obj = new Proxy(target, {}); obj.point = 100; console.log(obj.point); // 100 // 1. obj.point = 100; 100을 point에 할당하므로 setter임 // 2. set() 트랩을 작성하지 않았으므로 target 오브젝트의 [[Set]]이 호출되며 파라미터 값으로 point와 100을 넘겨 줌 // 3. [[Set]]에서 {point: 100} 형태로 target 오브젝트에 설정함 // 4. obj.point; get() 트랩을 작성하지 않았으므로 target 오브젝트의 [[Get]]이 호출됨 // 5. 이것은 Proxy를 사용하지 않아도 됨
-
set()
트랩이 호출되면 엔진이 실행 환경을 분석하여 파라밑터 값을 설정 함const target = {}; const handler = { set(target, key, value, receiver) { target[key] = value + 200; }, }; const obj = new Proxy(target, handler); obj.point = 100; console.log(obj.point); // 300 // 1. obj.point = 100; 을 실행하면 set() 트랩이 호출 됨 // 2. 트랩: set(target, key , value, receiver){...} 엔진이 target 파라미터에 target 오브젝트를 설정 함 // 3. key 파라미터에 "point"를 설정하고 value 파라미터에 100을 설정함 // 4. receiver 파라미터에 Proxy 또는 Proxy를 상속받은 오브젝트를 설정 함 // 5. 파라미터 이름으로 값을 매핑하지 않고 파라미터 순서로 매핑함, 이름을 자유롭게 사용할 수 있음
2. set() 트랩 호출
- 아래처럼 값을 할당하면
set()
트랩이 호출 됨 - 프로퍼티에 값을 할당할 때
proxy[key] = 100
-
Object.create(proxy, {프로퍼티})
- 인스턴스에 없는 프로퍼티를 설정할 때
const target = {}; const handler = { point: 700, set(target, key, value, receiver) { target[key] = value + 200; }, }; const proxy = new Proxy(target, handler); const obj = Object.create(proxy, { bonus: { value: 500, writable: true }, }); obj.point = 100; console.log(obj.point); // 300 // 1. const obj = Object.create(proxy, {...}); proxy 인스턴스를 상속받아 인스턴스를 생성함 // 2. proxy 인스턴스에 연결된 handler와 target을 사용할 수 있음 // 3. bonus: {value: 500, writable: true} obj 인스턴스 프로퍼티로 값을 설정함, 즉 obj.bonus에 500이 설정됨 // 4. obj.point = 100; obj 인스턴스 프로퍼티로 point가 없음 set() 트랩이 호출됨 // 5. 트랩: target[key] = value + 200; target에 {point: 300}을 설정함 // 6. obj.point, obj 인스턴스 프로퍼티로 point를 검색함 point가 없음 // 7. target에 point를 검색함 point 값인 300이 반환됨 // 8. handler에서 point를 검색하지 않음 {point: 700}이 있지만 반환되지 않음, {point: 700}이 있지만 반환되지 않음
- 인스턴스에 있는 프로퍼티를 설정 할 때
const target = {}; const handler = { set(target, key, value, receiver) { target[key] = value + 200; }, }; const proxy = new Proxy(target, handler); const obj = Object.create(proxy, { point: { value: 100, writable: true }, }); obj.point = 700; console.log(obj.point); // 700 console.log(target.point); // undefined // 1. const obj = Object.create(proxy, {...}); proxy 인스턴스를 상속받아 인스턴스를 생성함 // 2. point: {value: 100, writabel: true} obj 인스턴스 프로퍼티로 값을 설정함. 즉, obj.point에 100이 설정됨 // 3. obj.point = 700; obj 인스턴스 프로퍼티 point가 있음 set() 트랩이 호출되지 않음 // 4. {point: 100}이 obj 인스턴스 프로퍼티로 설정되고 obj.__proto__에 handler와 target이 설정되므로 point를 먼저 인식하기 때문임 // 5. {point: 100}의 value 값을 700으로 변경함 // 6. 값을 바꾸려면 {writable: true} 이여야 함, ES5 "프로퍼티 디스크립트" 참고 // 7. obj.point obj 인스턴스 프로퍼티인 point 값을 반환함, 바뀐 값인 700이 출력됨 // 8. target.point target 오브젝트에 point 프로퍼티가 없으므로 undefined가 출력됨
Reflect.set()
-
set()
트랩에서target
값을 설정해야 함const target = {}; const handler = { set(target, key, value, receiver) { // target[key] = value + 200; }, }; const proxy = new Proxy(target, handler); obj.point = 100; console.log(obj.point); // undefined // 1. 트랩 : set(target, key, value, receiver) {...} set() 트랩에서 파라미터로 받은 {point: 100}이 target 오브젝트에 자동으로 설정되지 않음 // 2. set() 트랩에서 target 오브젝트에 {key: value}를 설정해야 함, 값 설정이 setter의 기본 오퍼레이션임 // 3. console.log(obj.point); obj 인스턴스 전체에 point가 없으므로 undefined가 출력됨
3. set() 트랩 준수사항
-
트랩 준수 사항(invariant)
- 트랩에서 준수 사항을 지키지 않으면 에러가 발생하거나 처리되지 않음
- 모든 트랩에 준수 사항이 있음
-
target
의 프로퍼티가data
디스크립터 일 때[[Writable]]: flase
또는[[Configurable]]: false
이면 프로퍼티 값을 설정할 수 없음
const target = {}; Object.definePropert(target, 'point', { value: 500, writable: false, }); const handler = { set(target, key, value, receiver) { target[key] = value + 200; }, }; const obj = new Proxy(target, handler); console.log((obj.point = 100)); // 100 console.log(obj.point); // 500 // 1. {writable: false}가 디폴트이지만 설명을 위해 작성함 // 2. 트랩: target[key] = value + 200;에서 point 프로퍼티가 {writable: false}이므로 point 프로퍼티 값을 변경할 수 없음 // 3. 그렇다고 에러가 발생하지 않음 {obj.point = 100}에서 100이 반환됨 // 4. console.log(obj.point); obj.point의 초깃값인 500이 출력됨
-
target
의 프로퍼티가 악세서 디스크립터 일 때[[Configurable]]: false
이면 프로퍼티 값을 설정 할 수 없음