>  기사  >  웹 프론트엔드  >  당신의 믹스인은 정말로 ECMAScript 5와 호환되나요?_기본

당신의 믹스인은 정말로 ECMAScript 5와 호환되나요?_기본

WBOY
WBOY원래의
2016-05-16 17:37:421052검색

저는 최근 ECMAScript 5를 최대한 활용해야 하는 클라이언트와 프로젝트를 진행하고 있었는데 매우 흥미로운 문제에 직면했습니다. 문제는 JavaScript에서 한 개체의 속성이나 메서드를 다른 개체에 혼합하는 매우 일반적인 패턴인 믹스인에서 비롯됩니다.

대부분 믹스인의 기능은 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

function mixin(수신자, 공급자) {
for (공급업체의 var 속성) {
                                                                                       ~                                           >

이 mixin() 함수에서 for 루프는 공급자 객체의 속성을 반복하고 이를 수신자 객체에 할당합니다. 거의 모든 JavaScript 라이브러리에는 다음과 같은 코드를 작성할 수 있는 유사한 기능이 있습니다.


코드 복사

코드는 다음과 같습니다.mixin(object, { name : "니콜라스", sayName: function() {
console.log(this.name);
}
});
object.sayName(); // "Nicholas" 출력




이 예에서 객체 object는 속성 이름과 sayName() 메서드를 받습니다. 이는 ECMAScript 3에서는 잘 작동하지만 ECMAScript 5에서는 그렇지 않습니다.

제가 겪고 있는 문제는 다음과 같습니다.

코드 복사

코드는 다음과 같습니다.(function() { // 나중에 작성 var name;
mixin(object, {
get name() { return name;

}
});

// 나중이라고 가정하겠습니다
name = "Nicholas";

}());

console.log(object.name); // 정의되지 않음


이 예는 다소 부자연스러워 보이지만 문제를 정확하게 설명합니다. 혼합된 속성은 ECMAScript 5의 새로운 기능인 getter 속성 접근자를 사용합니다. getter가 초기화되지 않은 지역 변수 이름을 참조하므로 속성이 정의되지 않습니다.

나중에 접근자 getter가 유효한 값을 반환할 수 있도록 name에 값이 할당됩니다. 불행하게도 object.name(혼합 속성)은 항상 정의되지 않은 값을 반환합니다.

무슨 일이에요?

mixin() 함수를 주의 깊게 분석해 보겠습니다. 실제로 루프 문에서는 속성이 한 개체에서 다른 개체로 재할당되지 않습니다. 실제로는 동일한 이름의 속성을 생성하고 공급자 개체의 접근자 메서드 getter의 반환 값을 할당합니다. (주석: 대상 객체는 getter 메서드를 가져오는 것이 아니라 getter 메서드의 반환 값을 가져옵니다. @justjavac)

이 예에서 mixin() 프로세스는 실제로 다음과 같습니다.

코드 복사

코드는 다음과 같습니다.receiver.name = 공급자.이름;
receiver.name 속성이 생성되고 공급자.name 값이 할당됩니다. 물론,supplyer.name에는 지역 변수 name의 값을 반환하는 getter 메소드가 있습니다. 이때 name의 값은 정의되지 않았으므로 Receiver.name에 해당 값이 저장됩니다. Receiver.name에 대해 생성된 getter 메서드가 없으므로 해당 값은 변경되지 않습니다.

이 문제를 해결하려면 속성 설명자(주석: 설명자)를 사용하여 한 개체의 속성을 다른 개체에 혼합해야 합니다. mixin()의 순수 ECMAScript 5 버전은 다음과 같습니다:

코드 복사

코드는 다음과 같습니다.function mixin(수신자, 공급자) { Object.keys(supplier).forEach(function(value, property) { Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
});
}

이 새 버전의 함수에서는 Object.keys()를 사용하여 공급자 객체의 모든 열거 속성을 포함하는 배열을 얻습니다. 그런 다음 foreach() 메서드를 사용하여 이러한 속성을 반복합니다. Object.getOwnPropertyDescriptor() 메서드를 호출하여 공급자 개체의 각 속성 설명자(설명자)를 가져옵니다.

설명자에는 getter 및 setter 메서드를 포함한 모든 속성 정보가 포함되어 있으므로 설명자를 Object.defineProperty()에 직접 전달하여 수신자 객체에 동일한 속성을 생성할 수 있습니다. 이 새로운 버전의 mixin()을 사용하면 이전에 발생한 문제를 해결하고 원하는 결과를 얻을 수 있습니다. getter 메소드가 공급자에서 수신자로 올바르게 전달됩니다.

물론, 여전히 이전 브라우저를 지원해야 한다면 ECMAScript 3으로 대체되는 기능이 필요합니다.

코드 복사 코드는 다음과 같습니다.

function mixin(수신자, 공급자) {
if (Object.keys) {
Object.keys(supplier).forEach(function(value, property) {
Object.defineProperty(receiver, property, Object.getOwnPropertyDescriptor(supplier, property));
} );
} else {
for (공급업체의 var 속성) {
if (supplier.hasOwnProperty(property)) {
receive[property] = 공급자[property];
}
}
}
}

mixin() 함수를 사용해야 하는 경우 ECMAScript 5, 특히 getter 및 setter 메서드에서 제대로 작동하는지 다시 확인하세요. 그렇지 않으면 당신도 나처럼 실수에 빠지게 될 것이다.

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