원형 체인 납치 기반의 전단 코드 삽입 실천
말뚝삽입기초개념
앞부분 말뚝의 기본 이념은 이 문제로 표현할 수 있다. 만약에 업무에 광범위하게 사용되는 함수가 있다면 우리는 그 함수를 호출하는 업무 코드도 바꾸지 않고 이 함수 코드를 바꾸지 않는 전제에서 그 집행 전후에 우리의 정의로운 논리를 주입할 수 있을까?
더욱 구체적인 예를 들어 만약에 업무 논리에 많은
console.log
로그 코드가 있다면 우리는 이 코드를 바꾸지 않는 전제에서 이log 내용을 네트워크를 통해 보고할 수 있습니까?하나의 간단한 사고방식은 다음과 같다.console.log
을 이 함수로 대체한다.만일 우리의 해법이 통용성을 갖추기를 원한다면 첫 번째 단계의 조작을 고급 함수로 범용하기 어렵지 않다.
function withHookBefore (originalFn, hookFn) {
return function () {
hookFn.apply(this, arguments)
return originalFn.apply(this, arguments)
}
}
그래서 우리의 삽입 코드는 매우 간결하게 되었다.이렇게 하면 됩니다.
console.log = withHookBefore(console.log, (...data) => myAjax(data))
원생적
console.log
은 우리가 삽입한 논리 이후에 계속될 것이다.다음은 이 문제를 고려한다. 우리가 외부로부터console.log
의 집행을 차단할 수 있을까?고급 함수가 생기면 이것도 마찬가지로 식은 죽 먹기다.function withHookBefore (originalFn, hookFn) {
return function () {
if (hookFn.apply(this, arguments) === false) {
return
}
return originalFn.apply(this, arguments)
}
}
갈고리 함수
false
만 되돌아오면 원 함수는 실행되지 않는다.예를 들어 다음과 같이 콘솔을 깔끔하게 조작할 수 있습니다.console.log = withHookBefore(console.log, () => false)
이것이 바로 브라우저에서 하늘과 태양을 훔치는 기본 원리다.
DOM API에 대한 삽입
단순한 함수 교체로는 비교적 큰 HACK 조작을 완성하기에는 부족하다.다음은 브라우저의 모든 사용자 이벤트를 어떻게 포착합니까?
너는 당연히 맨 윗부분
document.body
에 각종 이벤트listener를 추가해서 이 요구를 달성할 수 있다.그러나 이때의 문제는 하위 요소e.stopPropagation()
를 사용하여 사건의 거품을 막으면 맨 윗부분 노드에서 이 사건을 받을 수 없다는 것이다.설마 우리가 모든 DOM의 요소를 훑어보고 그 사건 감청기를 고쳐야 하는 건 아니겠지?폭력보다 원형 체인에서 글을 쓸 수 있다.DOM 요소에 대해
addEventListener
를 사용하여 이벤트 리셋을 추가하는 것은 더 이상 정상적이지 않은 작업이다.이 방법은 사실 공공의 원형 체인에 위치하고 우리는 앞의 고급 말뚝 함수를 통해 그것을 납치할 수 있다.EventTarget.prototype.addEventListener = withHookBefore(
EventTarget.prototype.addEventListener,
myHookFn //
)
하지만 그것만으로는 부족하다.이런 방식을 통해 진정으로 추가된listener 매개 변수는 바뀌지 않았기 때문이다.그럼,listener 파라미터를 납치할 수 있습니까?이때 우리는 실제로 이런 고급 함수가 필요하다.
이 함수는 대략 이렇게 생겼다.
function hookArgs (originalFn, argsGetter) {
return function () {
var _args = argsGetter.apply(this, arguments)
// arguments
for (var i = 0; i < _args.length; i++) arguments[i] = _args[i]
return originalFn.apply(this, arguments)
}
}
이 고급 함수와 기존
withHookBefore
을 결합하면 우리는 완전한 납치 방안을 설계할 수 있다.hookArgs
의 매개 변수를 addEventListener
로 대체합니다.listener
리셋이다.이 리셋을 withHookBefore
맞춤형 버전으로 바꾸십시오.listener
에 추가한 갈고리에서 맞춤형 이벤트 수집 코드를 실행합니다.이 시나리오의 기본 논리 구조는 다음과 같습니다.
EventTarget.prototype.addEventListener = hookArgs(
EventTarget.prototype.addEventListener,
function (type, listener, options) {
const hookedListener = withHookBefore(listener, e => myEvents.push(e))
return [type, hookedListener, options]
}
)
위의 코드가
addEventListener
를 포함하는 모든 실제 업무 코드를 실행하기 전에 실행된다면 우리는 이벤트 거품의 제한을 초월하여 우리가 흥미를 느끼는 모든 사용자 이벤트를 수집할 수 있습니다:)전단 프레임에 대한 말뚝 꽂기
우리가 DOM API에 말뚝을 꽂는 원리를 이해한 후에 앞부분 프레임의 API에 대해 고양이 그림처럼 할 수 있게 되었다.예를 들어 우리는 Vue에서 심지어 모든
this.$emit
정보를 수집할 수 있습니까?또한 원형 체인 납치를 통해 간단하게 실현할 수 있다.import Vue from 'vue'
Vue.prototype.$emit = withHookBefore(Vue.prototype.$emit, (name, payload) => {
//
console.log('emitting', name, payload)
})
물론 API 인터페이스가 완벽하게 봉인된 프레임워크를 이런 방식으로 맞춤형으로 제작하는 것은 최선의 실천에 어긋날 수 있다.그러나 기초 라이브러리나 개발자 도구를 개발해야 할 때 이 기술이 쓸모가 있다고 믿는다.예를 들면 다음과 같습니다.
총결산
지금까지 우리는 말뚝 꽂기 기술의 기본 개념과 약간의 실천을 소개했다.만약 당신이 흥미가 있다면, 좋은 소식은 우리가 자주 사용하는 말뚝 삽입 고급 함수를 상자를 열면 바로 사용할 수 있는 NPM 기초 라이브러리
runtime-hooks
로 봉인했다는 것입니다. 이 말뚝 삽입 함수들은 다음과 같습니다.withHookBefore
- 함수에 before 갈고리 추가withHookAfter
- 함수에 애프터 갈고리 추가hookArgs
-마개함수 매개 변수hookOutput
-마개함수 반환값P.S. 저희 베이스 샤먼의 전단팀 활약 구인 중, 이력서 요청xuebiat gaoding.com이야~
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.