더욱 세련된 이벤트 트리거 호환성
베이스 인터페이스 호환을 하는 것은if를 이용하여 클라이언트가 어떤 인터페이스를 지원하는지 판단하는 것이다.가장 유명한 예는 바로 사건이다.
var addEvent = function(e, what, how) {
if (e.addEventListener) e.addEventListener(what, how, false)
else if (e.attachEvent) e.attachEvent('on' + what, how)
}
요소에 이벤트를 연결할 때 발생할 수 있는 두 가지 상황인 표준 W3C DOM 인터페이스와 DHTML이 제공하는 인터페이스를 고려했습니다.물론 이 예는 아직 매우 거칠지만, 문제를 설명하기에는 충분하다.
원래의 방법은 호환층에서 현장 판단을 하고 해당하는if분지에 들어가는 것이다.이런 현장 판단의 방법은 효율이 결코 높지 않다는 것이 매우 명백하다.나중에 사람들은 이런 방법을 채택했다.
if (MSIE) {
addEvent = function(e, what, how) {
e.attachEvent('on' + what, how);
}
} else {
addEvent = function(e, what, how) {
e.addEventListener(what, how);
}
}
한 번의 판단 후 addevent에 다른 코드를 연결하여 실행할 때의 분기 판단을 없앴다.
안타깝게도 이 문제도 적지 않다.우선'attach Event'와'클라이언트는 MSIE'를 연결하는 것은 유행이 지난 생각이다.만약 마이크로소프트가 어느 날 양심을 발견하면 어떻게 합니까?이 일은 지금 일어났다. IE9은 DOM 인터페이스를 명확하게 지지했고, 심지어는 DOM3도 지지했다.결과적으로, 이 양심적 발견에 대한 행동은 많은 전방 라이브러리를 파괴하고, 그들은 코드를 수정해야만 했다. (IE8이 왔을 때와 같이)게다가 이런 방법은 '알 수 없는 클라이언트' 를 고려하지 않았다. 구글이 크롬을 발표한 후에도 많은 라이브러리에서 코드를 다시 쓰는 것을 초래한 것으로 알고 있다.
특성 검사
그럼 도대체 어떻게 해야 돼요?특성 검사는'새 클라이언트'가 가져오는 번거로움을 최대한 피할 수 있다. 즉, 라이브러리를 초기화할 때 정의된 코드를 통해 클라이언트가 가지고 있는 특성을 검사하고 이 검사 값을 이용하여 라이브러리 코드를 귀속시킬 수 있다.
var supportsAddEventListener = !!(checkerElement.addEventListener);
if (supportsAddEventListener) {
addEvent = function(e, what, how) {
e.addEventListener(what, how);
}
} else if (supportsAttachEvent) {
addEvent = function(e, what, how) {
e.attachEvent('on' + what, how);
}
}
특성 검출은 실제적으로'어떤 클라이언트 사용'과'어떤 특성 지원'을 결합시켜if분지로 하여금'특성 유무'(인터페이스 일치 여부)에 대한 판단을 직접 하게 함으로써 클라이언트 제조업체의'양심적 발견'으로 인한'호의적 나쁜 짓'을 없애는 것이다.사실 이렇게 하는 것도 역사적 흐름에 부합되는 선택이다. 표준 인터페이스가 점점 보급되고 클라이언트 간에 표징이 일치할 때 왜 일치하는 호환층 인터페이스를 하지 않는가?
떨어지다
이 코드들을 다시 봅시다.일반적으로 특성 검사를 이용하여 호환되는 코드는 다음과 같습니다.
if (new_interface_detected) {
comp = function() {uses_new_interface};
} else if (old_interface_detected) {
comp = function() {uses_old_interface};
} else {
throw new Error('Unadaptable!')
}
다시 말하면 과정은 다음과 같다.
클라이언트가 새 인터페이스를 지원하면 호환층을 새 인터페이스에 연결합니다
그렇지 않으면 클라이언트가 오래된 인터페이스/불일치 인터페이스를 지원하면 호환층을 오래된 인터페이스에 연결합니다
그렇지 않으면, 가능하면 오류 응답을 드리겠습니다.
즉, 호환층 프로그램은 고공에서'떨어진다'는 것이다. 만약에 클라이언트가'고급'특성(새 인터페이스, 표준 인터페이스)을 지원한다면 이를'연결'하면 호환층에 귀착이 생긴다.그렇지 않으면 계속 아래로 떨어진다. 오, 낡은 인터페이스를 받으면 낡은 인터페이스를 사용한다.만약 계속 아무도 받지 못한다면, 팍, 땅에 넘어지고, 마지막 단숨에 "네가 사용하는 클라이언트가 너무 작아서, 나는 너를 어쩔 수 없다."라고 외쳤다.
이것은 무엇과 비교적 비슷합니까?
사실, 만약 당신이 자바스크립트 대상 시스템의 기리를 이해한다면, 당신은 이것이야말로 원형이 아니냐!원형 시스템은 이러한 추락을 이용하여 어떤 구성원을 찾고 이 대상에 정의되면 되돌아간다.그렇지 않으면 원형 체인을 따라 위로 검색하고 (그래, 이번에는 위로) 이렇게 반복해서 원형 체인까지 머리가 될 때까지undefined로 돌아간다.
하자면 해!여기서도 마찬가지로 addEvent를 예로 들 수 있다.먼저 다음과 같은 빈 드라이브를 정의합니다.
var nullDriver = {}
그 다음에 대상을 만들고 원형 체인을 가리키는 것이다.ECMA V5 시대에는 Object를 사용할 수 있었습니다.create, 아쉽게도 아직 N이 얼마나 오래된 클라이언트가 있기 때문에 (그렇지 않으면 호환성이 무엇입니까) 자신의 craft 함수:
var derive = Object.create ? Object.create: function() {
var T = function() {};
return function(obj) {
T.prototype = obj;
return new T
}
}()
이 용법은 네가 매우 이상하게 느낄 수도 있지만, 그것은 일하기에 조금도 문제가 없고, 속도도 느리지 않다. 즉, Object에 도달할 수 있다.create의 절반.우리는 이derive로 출발한다.
var dhtmlDriver = derive(nullDriver);
var dhtmlDriverBugfix = derive(dhtmlDriver);
이 버그는 일부 버그와 특수한 상황에 대한 특별 드라이브입니다.여기서 너는 그것을 소홀히 할 수 있다.자, DHTML에 addevent가 뭐였지?
if (supportsAttachEvent) {
dhtmlDriver.addEvent = function(e, what, how) {
e.attachEvent('on' + what, how)
}
}
그리고요?원형 체인의 맨 앞부분에 있는 것은 W3C의 표준 구동이어야 합니다. 쓰세요!
var w3cDriver = derive(dhtmlDriverBugfix);
var w3cDriverBugfix = derive(w3cDriver);
if (supportsAddEventListener) {
w3cDriver.addEvent = function(e, what, how) {
e.addEventListener(what, how)
}
}
마지막으로, 우리는 물건을 놓고 마지막으로 호출하는 인터페이스를 만들 것이다.(w3cdriver Bugfix가 너무 못생겨서...)
var driver = derive(w3cDriverBugfix);
그리고 호출했습니다.보아하니, 이것은 무섭게 생긴 지점의 판단을 간단하고 효과적으로 하지만, fallback의 본색을 잃지 않는다. 지원하는 addEvent Listener에서 addEvent를 호출하는 것은 w3cdriver를 호출하는 것과 같다.ddEvent,ddEvent Listener를 지원하지 않는 클라이언트에서 끝까지 떨어집니다. 예를 들어 dhtmlDriver를 호출합니다.addEvent.또 버그믹스를 진행하는 것도 쉽다. 전문적인 버그믹스 층에서 훅을 할 수 있지만 기존 층은 전혀 영향을 받지 않는다.
잠깐만, 이렇게 많이 물려받았어.
느릴까요?물론 그렇게 깊은 원형 체인은 틀림없이 느릴 것이다. 그러나 나는 방법이 있다.대상의 속성을 쓸 때 무슨 일이 일어났는지 기억하십니까?
var ego = function(x) {return x}
for (var each in driver) {
if (! (each in nullDriver)) {
driver[each] = ego(driver[each])
}
}
맞아요. 원래 고기업이 원형 체인 위에 있는 방법은'
총결산
비록 여기서 호환을 말하지만, 그것의 정수는 언어 특성상 원형 계승을 이용하여, 우리는 매우 우아하게 이 골치 아픈 조작을 완성할 수 있다.그래, 틀의 아름다움은 겉모습만 있는 것이 아니라, 그 안쪽은 가장 짜증나는 내부라도 우아해야 한다.
이곳의 기술은dess에서 찾을 수 있습니다.
typeof.net
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.