ES6의 Reflect 접근 방식 요약
1. 개요
Object 객체의 언어 내부에 명시적으로 속하는 방법(예: Object.defineProperty)을 Reflect 객체에 배치합니다
일부 Object 메서드의 반환 결과를 수정하여 보다 합리적으로 만듭니다.예를 들어, Object.defineProperty(obj,name,desc)는 속성을 정의할 수 없을 때 오류가 발생하고 Reflect.defineProperty(obj, name, desc)는 false를 반환합니다
Object 작업을 함수 비헤이비어로 만듭니다.일부 Object 작업은 명령식입니다(예: name in obj, delete obj[name]). Reflect.has(obj, name) 및 Reflect.deleteProperty(obj, name)를 함수 비헤이비어로 만듭니다
Reflect 대상의 방법은 Proxy 대상의 방법과 일일이 대응하고 Proxy 대상의 방법이라면 Reflect 대상에서 대응하는 방법을 찾을 수 있다
//
Function.prototype.apply.call(Math.floor, undefined, [8.75]) // 8
//
Reflect.apply(Math.floor, undefined, [20.5]) // 20
2. 정적 방법
Reflect 객체는 모두 13가지 정적 방법입니다.
Reflect.apply(target, thisArg, args)
Reflect.construct(target, args)
Reflect.get(target, name, receiver)
Reflect.set(target, name, value, receiver)
Reflect.defineProperty(target, name, desc)
Reflect.deleteProperty(target, name)
Reflect.has(target, name)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)
1.Reflect.get(target, name, receiver)
Reflect.get 방법은 target 대상의name 속성을 찾고 되돌려줍니다. 이 속성이 없으면undefined로 되돌려줍니다.
var obj = {
name: 'houfee',
age: 24,
get func() {
return this.name + this.age
}
}
console.log(Reflect.get(obj, 'name')) // houfee
console.log(Reflect.get(obj, 'age')) // 24
console.log(Reflect.get(obj, 'func')) // houfee24
name 속성이 읽기 함수 (Getter) 를 배치하면 읽기 함수의this귀속receiver.
this 지향 변경
var obj = {
name: 'houfee',
age: 24,
get func() {
return this.name + this.age
}
}
var obj2 = {
name: 'houyue',
age: 14,
}
console.log(Reflect.get(obj, 'name')) // houfee
console.log(Reflect.get(obj, 'age')) // 24
console.log(Reflect.get(obj, 'func', obj2)) // houyue14
첫 번째 매개변수가 객체가 아닌 경우 Reflect.get 방법이 틀릴 수 있습니다.
2.Reflect.set(target, name, value, receiver)
Reflect.set 방법은 target 대상의name 속성을value와 같이 설정합니다.
var obj = {
name: 'houfee',
set func(value) {
return this.name = value
}
}
var obj2 = {
name: 'houyue'
}
console.log(Reflect.set(obj, 'name', 'houyue')) // true
console.log(Reflect.set(obj, 'func', 'houyue')) // true
console.log(obj) // {name: "houyue", age: 24}
name 속성에 값 부여 함수를 설정하면 값 부여 함수의this가receiver에 귀속됩니다.
var obj = {
name: 'houfee',
set func(value) {
return this.name = value
}
}
var obj2 = {
name: 'zhangsan'
}
console.log(Reflect.set(obj, 'func', 'houyue', obj2)) // true
console.log(obj) // {name: "houfee"}
console.log(obj2) // {name: "houyue"}
만약 Proxy 대상과 Reflect 대상이 연합하여 사용한다면 전자는 값을 부여하는 동작을 차단하고 후자는 값을 부여하는 기본 행위를 완성하며receiver로 전송되면 Reflect입니다.set은 Proxy를 트리거합니다.defineProperty 차단
Proxy와 Reflect는 다음과 같이 사용됩니다.
let p = {
a: 'a'
};
let handler = {
set(target, key, value, receiver) {
console.log('set');
Reflect.set(target, key, value, receiver)
},
defineProperty(target, key, attribute) {
console.log('defineProperty');
Reflect.defineProperty(target, key, attribute);
}
};
let obj = new Proxy(p, handler);
obj.a = 'A';
// set
// defineProperty
위 코드에서 Proxy.set 차단 안에 Reflect를 사용했습니다.set, receiver가 전송되어 Proxy를 터치합니다.defineProperty 차단프록시 때문이야.set의receiver 매개 변수는 항상 현재 Proxy 실례 (즉 위의 obj) 를 가리키고 Reflect입니다.set이receiver에 전송되면 속성을receiver 위(즉obj)에 값을 부여하여 defineProperty 차단을 터치합니다.만약 Reflect.set이receiver에 전송되지 않으면 defineProperty 차단을 터치하지 않습니다.
let p = {
a: 'a'
};
let handler = {
set(target, key, value, receiver) {
console.log('set');
Reflect.set(target, key, value)
},
defineProperty(target, key, attribute) {
console.log('defineProperty');
Reflect.defineProperty(target, key, attribute);
}
};
let obj = new Proxy(p, handler);
obj.a = 'A'; // set
첫 번째 매개변수가 객체가 아닌 경우 Reflect.set은 오류를 보고합니다.
3.Reflect.has(obj, name)
Reflect.has 방법은 name in obj의 in 연산자에 대응합니다.
var myObject = {
foo: 1,
};
//
console.log('foo' in myObject); // true
//
console.log(Reflect.has(myObject, 'foo')); // true
이 방법은 브리 값을 되돌려줍니다.삭제에 성공하거나 삭제된 속성이 존재하지 않으면true로 되돌아오기;삭제에 실패했습니다. 삭제된 속성이 여전히false로 되돌아옵니다.
4. Reflect.deleteProperty(obj, name)
Reflect.deleteProperty 메서드는 개체의 속성을 삭제하는 데 사용되는 delete obj[name]와 같습니다.
const myObj = {
foo: 'bar'
};
//
delete myObj.foo;
//
Reflect.deleteProperty(myObj, 'foo');
이 방법은 브리 값을 되돌려줍니다.삭제에 성공하거나 삭제된 속성이 존재하지 않으면true로 되돌아오기;삭제에 실패했습니다. 삭제된 속성이 여전히false로 되돌아옵니다.
5. Reflect.construct(target, args)
Reflect.construct 방법은 new target (...args) 과 같습니다. 이것은 new를 사용하지 않고 구조 함수를 호출하는 방법을 제공합니다.
function Func(name) {
this.name = name
}
// new
const instance = new Func(' ')
// Reflect.construct
const instance = Reflect.construct(Func, [' '])
6. Reflect.getPrototypeOf(obj)
Reflect.getPrototypeOf 방법은 Object에 대응하는 대상의 proto 속성을 읽는 데 사용됩니다.getPrototypeOf(obj) .
function Func(name) {
this.name = name
}
// new
const instance = new Func(' ')
Object.getPrototypeOf(instance) === Func.prototype
// Reflect.construct
const instance = Reflect.construct(Func, [' '])
Reflect.getPrototypeOf(instance) === Func.prototype
Reflect.getPrototypeOf 및 Object.getPrototypeOf의 차이점은 다음과 같습니다.
매개변수가 객체가 아닌 경우 Object.getPrototypeOf에서 이 인자를 대상으로 바꾸고 다시 실행합니다. Reflect.getPrototypeOf가 오류를 보고합니다.
7. Reflect.setPrototypeOf(obj, newProto)
Reflect.setPrototypeOf 방법은 대상의 프로토 속성을 설정하고 첫 번째 매개 변수 대상을 bject에 대응하는 데 사용됩니다.setPrototypeOf(obj, newProto) .
function Func(name) {
this.name = name
}
function Age(age) {
this.age = age
}
// new Age instance
var instance = new Func(' ')
Object.setPrototypeOf(instance, Age.prototype)
// Reflect.construct
var instance = Reflect.construct(Func, [' '])
Reflect.setPrototypeOf(instance, Age.prototype)
첫 번째 매개변수가 객체가 아닌 경우 Object.setPrototypeOf는 첫 번째 매개변수 자체를 Reflect.setPrototypeOf가 오류를 보고합니다.
첫 번째 매개변수가 undefined 또는 null이면 Object.setPrototypeOf 및 Reflect.setPrototypeOf 모두 오류를 보고합니다.
8. Reflect.apply(func, thisArg, args)
Reflect.apply 방법은 Function과 같습니다.prototype.apply.this 객체를 바인딩한 후 주어진 함수를 실행하는 데 사용되는 call(func, thisArg, args)일반적으로 함수의this 대상을 연결하려면 fn.apply(obj,args), 그러나 함수가 자신의 apply 방법을 정의하면Function으로만 쓸 수 있습니다.prototype.apply.call(fn,obj,args)은 Reflect 대상을 사용하면 이런 조작을 간소화할 수 있다.
const ages = [11, 33, 12, 54, 18, 96];
//
const youngest = Math.min.apply(Math, ages);
const oldest = Math.max.apply(Math, ages);
const type = Object.prototype.toString.call(youngest);
//
const youngest = Reflect.apply(Math.min, Math, ages);
const oldest = Reflect.apply(Math.max, Math, ages);
const type = Reflect.apply(Object.prototype.toString, youngest, []);
9. Reflect.defineProperty(target, propertyKey, attributes)
Reflect.defineProperty 메서드는 기본적으로 Object와 같습니다.개체의 속성을 정의하는 데 사용되는 defineProperty앞으로 후자는 점차 폐지될 것이니 지금부터 Reflect를 사용하세요.defineProperty 대신 사용할 수 있습니다.
function MyDate() {
/*…*/
}
//
Object.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
//
Reflect.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
만약 Reflect.defineProperty의 첫 번째 파라미터가 대상이 아니면 Reflect와 같은 오류가 발생합니다.defineProperty(1, 'foo') .
10. Reflect.getOwnPropertyDescriptor(target, propertyKey)
Reflect.getOwnPropertyDescriptor는 기본적으로 Object와 같습니다.getOwnPropertyDescriptor, 지정한 속성을 얻을 수 있는 설명 대상입니다. 나중에 후자를 대체할 것입니다.
var myObject = {};
Object.defineProperty(myObject, 'hidden', {
value: true,
enumerable: false,
});
//
var theDescriptor = Object.getOwnPropertyDescriptor(myObject, 'hidden');
//
var theDescriptor = Reflect.getOwnPropertyDescriptor(myObject, 'hidden');
Reflect.getOwnPropertyDescriptor 및 Object.getOwnPropertyDescriptor의 차이점 중 하나는 첫 번째 인자가 대상이 아니라면 Object입니다.getOwnPropertyDescriptor(1,'foo') 오류 없이 undefined로 되돌아오기,
Reflect.getOwnPropertyDescriptor(1,'foo')에서 오류가 발생하여 파라미터가 불법임을 나타냅니다.
11.Reflect.isExtensible (target)
Reflect.isExtensible 메서드는 Object에 해당합니다.isExtensible, 현재 객체의 확장 가능 여부를 나타내는 부울 값을 반환합니다.
const myObject = {};
//
Object.isExtensible(myObject) // true
//
Reflect.isExtensible(myObject) // true
매개변수가 객체가 아닌 경우 Object.isExtensible는false를 되돌려줍니다. 대상이 아니면 원래 확장할 수 없는 것이고 Reflect입니다.isExtensible 에서 오류를 보고합니다.
12. Reflect.preventExtensions(target)
Reflect.preventExtensions 대응 Object.객체를 확장할 수 없게 만드는 데 사용되는 preventExtensions 메서드입니다.작업이 성공했는지 여부를 나타내는 부울 값을 되돌려줍니다.
var myObject = {};
//
Object.preventExtensions(myObject) // Object {}
//
Reflect.preventExtensions(myObject) // true
매개변수가 객체가 아닌 경우 Object.preventExtensions는 ES5 환경에서 오류를 보고하고 ES6 환경에서 전송된 파라미터를 되돌려줍니다. Reflect.preventExtensions 가 오류를 보고합니다.
13. Reflect.ownKeys (target)
Reflect.ownKeys 메서드는 기본적으로 Object와 같은 객체의 모든 속성을 반환하는 데 사용됩니다.getOwnPropertyNames 및 Object.getOwnPropertySymbols의 합.
var myObject = {
foo: 1,
bar: 2,
[Symbol.for('baz')]: 3,
[Symbol.for('bing')]: 4,
};
//
Object.getOwnPropertyNames(myObject)
// ['foo', 'bar']
Object.getOwnPropertySymbols(myObject)
//[Symbol(baz), Symbol(bing)]
Reflect.ownKeys(myObject)
// ['foo', 'bar', Symbol(baz), Symbol(bing)]
3. 인스턴스: Proxy를 사용하여 관찰자 모드 구현
관찰자 모드(Observer mode)는 함수가 자동으로 데이터 객체를 관찰하고 객체가 변하면 함수가 자동으로 실행되는 것을 말한다.
const person = observable({
name: ' ',
age: 20
});
function print() {
console.log(`${person.name}, ${person.age}`)
}
observe(print);
person.name = ' '; // // , 20
위 코드에서 데이터 대상인person은 관찰 목표이고 함수print는 관찰자이다.데이터 대상이 바뀌면 print가 자동으로 실행됩니다.
다음은Proxy를 사용하여 관찰자 모드의 가장 간단한 실현, 즉observable과observe 두 함수를 실현하는 것을 씁니다.사고방식은observable 함수가 원시 대상의Proxy 에이전트를 되돌려주고 값을 부여하는 조작을 차단하며 관찰자의 각 함수를 촉발하는 것이다.
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {
set
});
function set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
queuedObservers.forEach(observer => observer());
return result;
}
위 코드에서 먼저 Set 집합을 정의했고 모든 관찰자 함수를 이 집합에 넣었다.그리고observable 함수는 원시 대상의 에이전트를 되돌려주고 값을 부여하는 작업을 차단합니다.차단 함수 set에서 모든 관찰자를 자동으로 실행합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.