2017-03-22 1 views
1

프록시를 사용하지 않는 속성에 액세스 할 때 typeError 대신 undefined를 반환하는 작은 래퍼를 작성했습니다. 코드는 다음과 같습니다.es6 proxy safe deep 객체

function proxify(event) { 
    var proxy = new Proxy(event, { 
     get: function (target, property) { 
      if (property in target) { 
       return target[property]; 
      } else { 
        return ''; 
      } 
      } 
     } 
    }); 
    return proxy; 
} 

속성이 1 단계 이상 누락 된 경우 작동합니다. 예를 들어, obj.something을 가정하는 것은 존재하지 않습니다

obj.something.else 

이 돌아갑니다 정의되지 않은

그러나

객체 속성 인 경우 깊은 중첩

obj.something.else.deeper 

나는 형식 오류를받을

내 질문은 깊이 중첩 된 객체에서 작동하도록 위의 함수를 어떻게 확장합니까?

당신은 당신의 proxify 함수에서 반환 값을 포장 할 필요가

+0

'obj.something'은 문자열이 아닌 다른 프록시를 반환해야합니다. – Bergi

+0

@Bergi 속성이 몇 단계에 있는지 확인할 방법이없는 것 같습니다. 부모가 존재하지 않는다는 것을 알고 있으면 다른 프록시를 호출 할 수 있습니다. 내가 뭔가를 놓치면 모범을 좋아할 것입니다. thx – Cyph

+0

확인할 방법이 없습니다. 단지 동적 속성 액세스 일뿐입니다. 항상 * 프록시를 반환해야합니다. – Bergi

답변

2

들으 : 모든 정직에서

function proxify(event) { 
    return isPrimitive(event) ? event : new Proxy(event, { get: getProp }); 
} 
function isPrimitive(v) { 
    return v == null || (typeof v !== 'function' && typeof v !== 'object'); 
} 
function getProp (target, property) { 
    if (property in target) { 
    return proxify(target[property]); 
    } else { 
    return proxify({}); 
    } 
} 

, 당신은 lodash's _.get() 또는 ramda's R.path() 같은 것을 사용하여 아마 더 낫다. 처음으로 getProp()에서 얼마나 많은 레이어가 깊게 호출되는지 알 수있는 방법이 없기 때문에 다음 속성 액세스가 가로 챌 수 있도록 항상 기본 값 또는 "사실"Proxy 인스턴스를 반환해야합니다). 반면에 _.get() 메소드는 문자열을 취하므로 초기 호출에서 많은 레벨을 액세스하려고 시도한다는 것을 즉시 알 수 있습니다.

+0

잘 모르겠다. func을 사용하여 예제를 보여줄 수 있습니까? 위에서 공유했습니다. – Cyph

+0

@Cyph 편집을 참조하십시오. – idbehold

+0

나는 약간의 테스트를했다. 나는 동의한다. lodash _.get은 지금가는 길 같습니다. 간단한 도트 접근 자 구문을 유지하려고했지만 주사위는 사용하지 않았습니다. – Cyph

2

idbehold에서 말한 것처럼 기본 값이나 새 프록시를 반환해야합니다. 당신은 loDash가 필요 없다고 생각합니다. 네, 중첩 된 프록시의 깊이를 관리 할 수 ​​있습니다! .

먼저 사용 (시뮬레이션 체인) :


난 당신이 뭘 원하는지 모르겠어요 때문에 ( 을 내 마지막 지점, deepProxy를 참조하지만, 나는 그 몇 가지 포인트에주의를 집중하고 싶습니다 이 약자로
function proxify(event){ 
    return isPrimitive(event) ? event : new Proxy(event,{ get: getProp }); 
} 

function isPrimitive(v){ 
    return v == null || (typeof v !== 'function' && typeof v !== 'object'); 
} 

function getProp(target, property){ 
    return (property in target) 
     ? proxify(target[property]) 
     : proxify({}); 
} 

이 코드는 중첩 된 속성, 을 시뮬레이션 처리 할 수 ​​있지만 회원 의존성을 부여하지 (할당 없음 다음 없음을 보존하기 때문에).

obj.something.else = 99; 
console.log(obj.something.else) // returning a new Proxy() 
을3210

IMO, 매우 구체적 인 경우에는 의미가 없거나 예약되어 있습니다. 다시 말하지만, 귀하의 목적에 달려 있습니다.

둘째 사용 (깊은 할당) : 새 객체를 설정하려고하면, 기본 체인 방식의 프록시를 사용하여 할당

-


기본하지 확장 할당

function proxify(defprop={}) 
{ 
    return new Proxy(defprop, handler); 
}; 
var handler = 
{ 
    get: function(target, property, receiver) 
    { 
     if(!(property in target)) 
      target[property] = proxify(); 
     return Reflect.get(target, property, receiver); 
    }, 
}; 

obj.something.else = 99; 
console.log(obj.something.else) // returning 99 

확장 (또는 중첩 된 객체)이 새 속성의 루트 만 트랩합니다. 더 이상 체인이 가능하지 않으며 적합하지 않으며 안전하지 않습니다. 이 과제를 가정 그러나 개체 속성은

obj.something.else.deeper

(잘못된 방법) 중첩 깊은 경우 :

Cyph :

는 다음과 같은 경우를 기억

var deeper = {toto: "titi"}; 
obj.something.else = deeper; 

console.log(obj.something.else.toto) 
// will return "titi" 

obj.something.else.toto.something.else = {tutu: "tata"}; 
// will return a typeError Again 

(좋은 방법) 체인 기능을 전달하려면 setter 트랩에서 실제 개체로 값 유형을 확인하고 각 루트 속성을 프록 시화해야합니다. 나머지 깊이는 게터 트랩에 의해 자연스럽게 변환됩니다.

var handler = 
{ 
    get: function(target, property, receiver) 
    { 
     if(!(property in target)) 
      target[property] = proxify(); 
     return Reflect.get(target, property, receiver); 
    }, 
    set: function(target, property, value, receiver) 
    { 
     // extend proxify to appended nested object 
     if(({}).toString.call(value) === "[object Object]") 
      value = deepApply(receiver, property, value); 

     return Reflect.set(target, property, value, receiver); 
    }, 
}; 
var deepApply = function(receiver,property, data) 
{ 
    var proxy = proxify(); 
    var props = Object.keys(data); 
    var size = props.length; 

    for(var i = 0; i < size; i++) 
    { 
     property = props[i]; 
     proxy[property] = data[property]; 
    } 
    return proxy; 
}; 

는 깊이


내 실제 솔루션을 읽는 당신을 초대에게 관리 : deepProxy

    오브젝트 구조 인 경우 레벨은 프로토 선언 를 통해 자동으로 정의 할 수 있습니다
  • 설정. 그러면 현재 바닥을 쉽게 알 수 있으며 각 레벨에 조건부 지침을 추가 할 수 있습니다.
  • 재산 접근은 그의 접근 장치에서 도달 할 수 있습니다.