>웹 프론트엔드 >JS 튜토리얼 >ES6의 프록시란 무엇입니까? Proxy에 대한 상세 분석

ES6의 프록시란 무엇입니까? Proxy에 대한 상세 분석

不言
不言원래의
2018-09-27 16:21:393541검색

이 기사의 내용은 ES6의 프록시란 무엇입니까? Proxy에 대한 자세한 분석은 특정 참고 가치가 있습니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

프록시는 중국어로 대행사를 의미합니다. 이 단어는 다른 프로그래밍 언어에서도 비슷한 의미를 갖습니다.

정의는

Proxy는 생성자입니다. js의 생성자의 일반적인 특징은 첫 글자가 대문자라는 것입니다. 새로운 Proxy(원본 객체, {proxy list}) 형식으로 객체를 생성합니다. 생성된 객체를 프록시 객체라고 합니다.
즉,

프록시 객체 = 새 프록시(원본 객체, {프록시 목록})

이러한 추가 프록시 객체가 생성되는 이유는 원본 객체를 변경하지 않고 그대로 유지할 수 있고, 새로운 기능을 추가할 수 있기 때문입니다. 프록시 객체, 또는 특정 기능을 수정하는 것입니다. 원본 객체는 적절한 시점에 롤백될 수 있습니다. 디자인 패턴 중 에이전트 패턴과 비교하고 이해할 수 있다.

사용 형식

var obj;
var proxyObj = new Proxy(obj, {
    对obj的操作1: 函数1,
    对obj的操作2: 函数2,
    ...
    
})

시작 예제

Proxy

var obj = {name:'fan',age:34}
console.info(obj.name)

var proxyObj = new Proxy(obj,{
    get:function(target,key,receiver){console.info(target,key,receiver); return 'no'}
})

console.info(proxyObj.name) 
console.info(proxyObj.abc)

의 기본 데모는 다음과 같이 설명됩니다.

  • Proxxy 객체는 obj 객체를 기반으로 생성된 새로운 객체입니다.

  • proxyObj.name은 프록시 개체의 이름 속성을 가져오는 것입니다. .연산자가 자동으로 get() 메서드를 호출합니다. 이는 매우 중요합니다. js에서 객체는 순서가 지정되지 않은 속성 모음입니다. 객체에는 속성만 있고 다른 것은 없습니다 그리고 우리는 종종 객체의 특정 메서드를 호출하는 것에 대해 이야기합니다. 예를 들어 배열 객체 arr의 정렬 메서드: arr.sort()도 여기서의 정렬입니다. arr 객체의 속성(더 엄밀하게 말하면 sort는 arr.__proto__ 객체의 속성입니다.) length 속성과 비교하면 sort 속성의 속성값은 함수이므로 이 함수를 실행하려면 뒤에 ()를 추가하세요. , 길이 속성의 값은 숫자값이므로 ()를 추가하지 않고 바로 사용 가능합니다. 다시 강조하겠습니다: 객체의 . 연산은 자동으로 get을 호출합니다. 물론 우리가 일반적으로 사용할 때에는 이 사실을 깨닫지 못합니다. .操作符会自动去调用get()方法。这一点非常重要,在js中,对象是属性的无序集合。对象只有属性,其他什么都没有. 而我们经常说的调用对象的某个方法:例如数组对象arr的sort方法:arr.sort(),这里的sort也是arr对象的属性(更严谨一点,sort是arr.__proto__这个对象的属性),与length属性相比,sort属性的属性值是一个函数,所以在它的后面加()来执行这个函数,而length属性的值是一个数值,所以不需要加()就可以直接使用。再次强调一下:对象的.操作,会自动去调用get。当然,我们平时使用.操作时,是没有感知到这一点的。

  • 在new Proxy的第二个参数中,明确设置了get的方法:当访问proxyObj的任意属性时,输出target,key,receiver的值,并统一返回no。所以proxyObj.name和proxyObj.abc都会得到no。

写到这里你会觉得原对象与代理对象之间有什么关系呢?为什么叫代理

new Proxy의 두 번째 매개변수에는 get 메소드가 명확하게 설정되어 있습니다. ProxyObj의 모든 속성에 액세스할 때 대상, 키 및 수신자의 값이 출력되고 no가 균일하게 반환됩니다. 따라서 ProxyObj.name과 ProxyObj.abc는 모두 no를 얻습니다.

이 글을 쓰면서 원본 개체와 프록시 개체의 관계는 무엇이라고 생각하시나요? 왜 에이전트라고 부르나요?

에이전트의 역할을 이해하세요
  • 에이전트는 연예인의 에이전트로 이해하시면 됩니다.

    外界 <----> 原对象;
    外界 <----> 代理对象 <------> 原对象;
    또한 요구 사항을 개선하기 위해 위 코드를 예로 들겠습니다. 누군가 obj의 이름을 묻는다면 그 사람에게 직접 알려주고, 누군가 obj의 나이를 묻는다면 5살 더 어린 나이를 반환하세요.
var obj = {name:'fan',age:34}
console.info(obj.age)           // 34
var proxyObj = new Proxy(obj,{
    get:function(target,key,receiver){
        console.info(target === obj);           //true
        console.info(receiver === proxyObj);    //true
        if('age' === key){
            return target[key] - 5;
        }
        else{
            return target[key]
        }
    }
})

console.info(proxyObj.age)  // 34- 5 = 29
는 다음과 같이 설명됩니다.

get 함수의 세 가지 매개변수: 대상, 키, 수신자. 대상은 원래 객체 j이고 키는 현재 속성 이름입니다. 수신자는 프록시 객체입니다. get 메소드에서 사용자 정의 처리를 수행할 수 있습니다.


프록시 객체와 원본 객체의 관계

var arr = [2,1]
var proxyArr = new Proxy(arr,{} )
proxyArr.push(3);
console.info(arr) // [2,1,3]
console.info(arr === proxyArr) // false
arr.sort();
console.info(proxyArr[0]) // 1

위 코드에서 이 프록시 객체는 특별한 작업을 수행하지 않습니다. 연예인의 매니저들은 외부 세계의 정보를 연예인 자신에게 전달하는 등 소극적인 업무를 수행하는 것으로 이해된다. 따라서 ProxyArr에서 수행되는 작업은 arr에 직접적인 영향을 미칩니다.

마찬가지로 arr에 대한 작업은 ProxyArr에도 영향을 미칩니다.

하지만 참고하세요: ProxyArr과 arr은 서로 다른 두 개체입니다: arr !== ProxyArr.

당신은 그것에 대해 생각할 수도 있습니다: 왜 ProxyArr이 푸시 메소드를 직접 사용할 수 있습니까? 그 이유는:

proxyArr.__proto__ === arr.__proto__ === Array.prototype

이전 방정식이 참인 이유는 새로운 프록시의 유전자에 의해 결정됩니다. 즉, 원래 개체가 프록시됩니다.

프록시 목록

새 프록시의 두 번째 매개변수에서 설정할 수 있는 프록시 속성은 다음과 같습니다.

var proxyObj = new Proxy(obj, {

    get: function(tagert,key,receiver){},
    set: function(tagert,key,receiver){},
    has: function(tagert,key){},
    deleteProperty: function(tagert,key){},
    ownKeys: function(tagert){},
    getOwnPropertyDescriptor: function(tagert,key){},
    defineProperty: function(tagert,key,desc){},
    preventExtensions: function(tagert){},
    getPrototypeOf: function(tagert){},
    isExtensible: function(tagert){},
    setPrototypeof: function(tagert,proto){},
    apply: function(tagert,obj,args){},
    construct: function(tagert,args){},
    
})
get() 프록시를 적용하면

배열 첨자가 음수 값이 될 수 있습니다
  • js에서 , 배열은 유효합니다. 아래 표는 0부터 시작합니다.

    var arr = [1,2,3];
    console.info(arr[0])  // 1
    console.info(arr[-1]) // undefined
    console.info(arr[100]) // undefined
    다음 표가 범위를 벗어나거나 음수 값을 갖는 경우 얻은 결과는 오류 대신 정의되지 않음에 유의할 가치가 있습니다.
이제 아래 표에서 배열이 음수 값을 가질 수 있기를 바랍니다. 규칙은 다음과 같습니다.

-n은 마지막에서 n번째 요소를 의미합니다. 예를 들어 -1은 마지막 요소의 첫 번째 요소를 의미합니다.
  • 프록시를 사용하여 다음과 같이 문제를 해결하세요.
var arr = [1,2,3];

var proxyArr = new Proxy(arr,{
    get: (target,prop)=>{
        let index = Number(prop);
        if(index < 0){
            prop = target.length + index;
        }
        return target[prop];
        
    }
})
console.info(arr[-1]);      // undefined
console.info(proxyArr[-1]); // 3
  • 참고:

  • Number()는 들어오는 값을 숫자 유형으로 변환할 수 있습니다. 숫자가 아닌 값 --> NaN;

  • proxyArr.push(3)인 경우 이때 prop이 'push'이므로 if 분기에 들어가지 않습니다.

  • proxyArr[-1]인 경우 이때 prop은 '-1'이므로 if 분기에 들어갑니다. prop을 -1에서 2로 변경하여 프록시 효과를 얻습니다.

    이때, ProxyArr을 배열로 사용할 수 있고, sort, push 등의 메소드를 호출할 수 있습니다. Array.isArray(proxyArr) === true🎜🎜🎜🎜물론 이를 팩토리 함수로 추가로 캡슐화할 수도 있습니다. 🎜
    function myArr(...args){
        var arr = new Array(...args);
    
        var proxyArr = new Proxy(arr,{
            get: (target,key)=>{
                let index = Number(key);
                if(index < 0){
                    key = target.length + index;
                }
                return target[key];
    
            }
        })
        return proxyArr;
    }
    var obj = myArr([1,2,3]);
    console.info(obj[0],obj[-1])
    🎜체인운영🎜
    var double = n => n*2;
    var pow2 = n => n*n;
    var half = n => n/ 2;
    var add1 = n => n+1;
    
    function pipe (num){
        let funs = []
        let obj = new Proxy({},{
            get:function(target,prop){
                if(prop === 'end'){
                    return funs.reduce((val,currentfn)=>currentfn(val),num);
                }else{
                    funs.push(window[prop])
                }
                return obj;
            }
        })
    
        return obj;
    };
    
    console.info( pipe(4).double.pow2.end);
    console.info( pipe(4).pow.double.pow2.add1.end);

    위 내용은 ES6의 프록시란 무엇입니까? Proxy에 대한 상세 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.