저는 최근 ECMAScript 5를 최대한 활용해야 하는 클라이언트와 프로젝트를 진행하고 있었는데 매우 흥미로운 문제에 직면했습니다. 문제는 JavaScript에서 한 개체의 속성이나 메서드를 다른 개체에 혼합하는 매우 일반적인 패턴인 믹스인에서 비롯됩니다.
대부분 믹스인의 기능은 다음과 같습니다.
코드 복사
이 예에서 객체 object는 속성 이름과 sayName() 메서드를 받습니다. 이는 ECMAScript 3에서는 잘 작동하지만 ECMAScript 5에서는 그렇지 않습니다.
제가 겪고 있는 문제는 다음과 같습니다.
코드 복사
}
});
// 나중이라고 가정하겠습니다
name = "Nicholas";
}());
이 예는 다소 부자연스러워 보이지만 문제를 정확하게 설명합니다. 혼합된 속성은 ECMAScript 5의 새로운 기능인 getter 속성 접근자를 사용합니다. getter가 초기화되지 않은 지역 변수 이름을 참조하므로 속성이 정의되지 않습니다.
나중에 접근자 getter가 유효한 값을 반환할 수 있도록 name에 값이 할당됩니다. 불행하게도 object.name(혼합 속성)은 항상 정의되지 않은 값을 반환합니다.
mixin() 함수를 주의 깊게 분석해 보겠습니다. 실제로 루프 문에서는 속성이 한 개체에서 다른 개체로 재할당되지 않습니다. 실제로는 동일한 이름의 속성을 생성하고 공급자 개체의 접근자 메서드 getter의 반환 값을 할당합니다. (주석: 대상 객체는 getter 메서드를 가져오는 것이 아니라 getter 메서드의 반환 값을 가져옵니다. @justjavac)
이 예에서 mixin() 프로세스는 실제로 다음과 같습니다.
코드 복사
코드 복사
이 새 버전의 함수에서는 Object.keys()를 사용하여 공급자 객체의 모든 열거 속성을 포함하는 배열을 얻습니다. 그런 다음 foreach() 메서드를 사용하여 이러한 속성을 반복합니다. Object.getOwnPropertyDescriptor() 메서드를 호출하여 공급자 개체의 각 속성 설명자(설명자)를 가져옵니다.
설명자에는 getter 및 setter 메서드를 포함한 모든 속성 정보가 포함되어 있으므로 설명자를 Object.defineProperty()에 직접 전달하여 수신자 객체에 동일한 속성을 생성할 수 있습니다. 이 새로운 버전의 mixin()을 사용하면 이전에 발생한 문제를 해결하고 원하는 결과를 얻을 수 있습니다. getter 메소드가 공급자에서 수신자로 올바르게 전달됩니다.
물론, 여전히 이전 브라우저를 지원해야 한다면 ECMAScript 3으로 대체되는 기능이 필요합니다.
mixin() 함수를 사용해야 하는 경우 ECMAScript 5, 특히 getter 및 setter 메서드에서 제대로 작동하는지 다시 확인하세요. 그렇지 않으면 당신도 나처럼 실수에 빠지게 될 것이다.