당신 의 mixin 은 정말 ECMAScript 5 를 호 환 합 니까?

4218 단어
저 는 최근 에 고객 과 합작 하 는 프로젝트 에서 ECMAScript 5 를 충분히 이용 해 야 합 니 다. 여기 서 아주 재 미 있 는 문 제 를 만 났 습 니 다.이 문 제 는 매우 흔히 볼 수 있 는 모델 에서 비롯 되 었 다. mixin, 즉 자바 스 크 립 트 에서 한 대상 의 속성 이나 방법 mixin 을 다른 것 으로 바 꾸 는 것 이다.
대부분의 mixin 기능 은 이렇게 보 입 니 다.
 
  
function mixin(receiver, supplier) {
    for (var property in supplier) {
        if (supplier.hasOwnProperty(property)) {
            receiver[property] = supplier[property];
        }
    }
}

이 mixin () 함수 에서 for 순환 이 supplier 대상 의 속성 을 옮 겨 다 니 며 receiver 대상 에 게 값 을 부여 합 니 다.거의 모든 자바 스 크 립 트 라 이브 러 리 는 이러한 코드 를 만 들 수 있 는 유사 한 기능 을 가지 고 있 습 니 다.
 
  
mixin(object, {
    name: "Nicholas",

    sayName: function() {
        console.log(this.name);
    }
});

object.sayName();       // outputs "Nicholas"


이 예제 에서 object 대상 은 속성 name 과 방법 sayName () 을 받 았 습 니 다.이 는 ECMAScript 3 에서 잘 작 동 되 고 있 지만 ECMAScript 5 에 서 는 그다지 낙관적 이지 않다.
이것 은 내 가 만난 문제 이다.
 
  
(function() {

    // to be filled in later
    var name;

    mixin(object, {
        get name() {
            return name;
        }
    });

    // let's just say this is later
    name = "Nicholas";

}());

console.log(object.name);       // undefined


이 예 는 좀 가식 적 으로 보이 지만, 그것 은 이 문 제 를 정확하게 묘사 했다.mixin 속성 을 진행 하려 면 ECMAScript 5 의 새로운 기능 을 사 용 했 습 니 다: getter 속성 액세스 기 입 니 다.getter 는 초기 화 되 지 않 은 부분 변수 name 을 참조 하기 때문에 이 속성 은 undefined 를 정의 하지 않 습 니 다.
나중에 name 은 액세스 기 getter 가 올 바른 값 을 되 돌 릴 수 있 도록 값 을 할당 하 였 습 니 다.불 행 히 도 object. name (mixin 의 속성) 은 undefined 로 되 돌아 갑 니 다.
이게 어떻게 된 거 죠?
우 리 는 mixin () 함 수 를 자세히 분석 했다.사실 순환 문 에 서 는 속성 을 한 대상 에서 다른 대상 에 게 다시 부여 하지 않 았 다.이것 은 실제 적 으로 같은 이름 의 속성 을 만 들 고 supplier 대상 의 액세스 방법 getter 의 반환 값 을 할당 합 니 다.(번역 주: 대상 이 얻 은 것 은 getter 라 는 방법 이 아니 라 getter 방법의 반환 값 입 니 다. @ justjavac)
이 예 에서 mixin () 의 과정 은 사실 다음 과 같다.
 
  
receiver.name = supplier.name;

속성 receiver. name 이 생 성 되 었 고 supplier. name 의 값 으로 할당 되 었 습 니 다.물론 supplier. name 은 로 컬 변수 name 의 값 을 되 돌려 주 는 getter 방법 이 있 습 니 다.이 때 name 의 값 은 undefined 이기 때문에 receiver. name 은 값 을 저장 합 니 다.receiver. name 에 getter 방법 을 만 들 지 않 았 기 때문에 값 은 영원히 변 하지 않 습 니 다.
이 문 제 를 해결 하려 면 속성 설명자 (번역 주: descriptor) 를 사용 하여 속성 을 한 대상 mixin 에서 다른 대상 으로 해 야 합 니 다.순수한 ECMAScript 5 버 전의 mixin () 은 이렇게 써 야 합 니 다.
 
  
function mixin(receiver, supplier) {

    Object.keys(supplier).forEach(function(value, property) {
        Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
    });
}


이 새 버 전 함수 에서 Object. keys () 는 하나의 배열 을 가 져 오 는 데 사 용 됩 니 다. supplier 대상 의 모든 매 거 진 속성 을 포함 합 니 다.그리고 foreach () 방법 은 이 속성 들 을 옮 겨 다 니 는 데 사 용 됩 니 다.Object. getOwnProperty Descriptor () 방법 으로 supplier 대상 의 모든 속성 설명자 (descriptor) 를 가 져 옵 니 다.
설명자 (descriptor) 는 getter 와 setter 방법 을 포함 하여 모든 속성 정 보 를 포함 하기 때문에 이 설명자 (descriptor) 는 Object. defineProperty () 에 직접 전달 하여 receiver 대상 에 같은 속성 을 만 들 수 있 습 니 다.이 새 버 전의 mixin () 을 사용 하면 앞에서 겪 은 문 제 를 해결 하고 원 하 는 결 과 를 얻 을 수 있 습 니 다.getter 방법 은 supplier 에서 receiver 로 정확하게 전달 되 었 습 니 다.
물론 오래된 브 라 우 저 를 지원 해 야 한다 면 함수 가 필요 합 니 다. 리 턴 된 ECMAScript 3:
 
  
function mixin(receiver, supplier) {
    if (Object.keys) {
        Object.keys(supplier).forEach(function(value, property) {
            Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
        });
    } else {
        for (var property in supplier) {
            if (supplier.hasOwnProperty(property)) {
                receiver[property] = supplier[property];
            }
        }
    }
}

mixin () 함 수 를 사용 하려 면 ECMAScript 5 에서 정상적으로 작 동 할 수 있 는 지, 특히 getter 와 setter 방법 을 자세히 확인 해 야 합 니 다.그렇지 않 으 면, 너 는 자신 이 나 와 같은 잘못 에 빠 졌 다 는 것 을 알 게 될 것 이다.

좋은 웹페이지 즐겨찾기