>웹 프론트엔드 >JS 튜토리얼 >JavaScript에서 원숭이 패치의 실용적인 사용

JavaScript에서 원숭이 패치의 실용적인 사용

William Shakespeare
William Shakespeare원래의
2025-02-17 12:52:10448검색

Pragmatic Uses of Monkey Patching in JavaScript

코어 포인트

JavaScript의 MP (Monkey Patch)는 프로그래머가 원래 소스 코드를 변경하지 않고 코드 세그먼트의 기본 동작을 재정의, 확장 또는 억제 할 수있는 기술입니다.

MP는 종종 나쁜 관행으로 간주되지만, 특히 원래 소스 코드를 변경할 수없는 경우 특정 요구에 맞게 타사 코드를 수정하는 데 유용한 도구로 사용될 수 있습니다.
    MP는 사용자 지정 동작으로 기존 기능을 덮어 쓰거나 원래 코드 전후에 사용자 정의 동작을 추가하여 방법을 향상 시키거나 AJAX 호출을 가로 채어 동작을 수정하는 데 사용될 수 있습니다.
  • MP는 코드에서 예측할 수없는 행동과 충돌을 일으킬 수 있으므로, 특히 코드 기반의 다른 곳에서 패치 된 메소드를 사용하는 경우 코드의 예측할 수없는 행동과 충돌을 일으킬 수 있으므로주의해서 사용해야합니다.
  • 잠재적 위험에도 불구하고 MP는 여전히 수리, 디버깅 및 구현을위한 강력한 도구가 될 수 있으며, JavaScript의 유연성과 동적 특성을 프로그래밍 언어로 강조합니다.
  • 이 기사는 Moritz Kröger와 Tom Greco가 검토했습니다. Sitepoint 컨텐츠를 최대한 활용 한 Sitepoint의 모든 동료 검토 자에게 감사합니다!
  • 당신은 당신을 미치게하는 작은 질문을 제외하고는 잘 작동하는 타사 코드를 사용한 적이 있습니까? 제작자가 성가신 콘솔 로그를 삭제하는 것을 잊어 버린 이유는 무엇입니까? API 호출이 한 가지 더 할 수 있다면 좋지 않을까요? 그렇다면 유지 관리자가 변경을 구현하는 것은 어려울 수 있습니다 (또는 불가능). 그러나 코드를 직접 변경하는 것은 어떻습니까? 소스 코드가없고 스스로 호스팅하고 싶지 않다면 어떻게해야합니까? JavaScript Monkey Patch의 World Journey에 오신 것을 환영합니다!
  • 이 기사에서는 원숭이 패치가 무엇인지 배우고 다른 예제를 통해이를 사용하여 우리의 요구에 맞게 타사 위젯의 기능을 변경합니다.
  • 원숭이 패치 란 무엇입니까?
원숭이 패치 (MP)는 원래 소스 코드를 변경하지 않고 코드 세그먼트의 기본 동작을 재정의, 확장 및 억제하는 데 사용되는 기술입니다. 이것은 원래 동작을

fix 버전으로 바꾸면 수행됩니다. Pragmatic Uses of Monkey Patching in JavaScript 이 기사는 피드백 양식을 포함하는 간단하고 스 와이프 가능한 팝업 창 (아래 이미지에 표시)을 표시하는 기존 피드백 상자 위젯을 사용합니다.

소스 코드는 MP 대상으로 사용하기위한 사용 사례를 포함하도록 수정되었습니다. 목표는 패치 할 특정 기능, 기능 또는 최소 수준 사용을 말합니다.

내가 만든 또 다른 수정은 코드 주변의 통화 함수 표현식 (iife)을 제거하는 것이 었습니다. 이것은 MP 기술에 중점을두기 위해 수행됩니다.

이 기사에서 논의 된 원숭이 패치를 포함하여 플러커에서 전체 예제를 찾을 수 있습니다.

원숭이 패치가 나쁜 연습이 아닌가? 우리가 시작하기 전에, 우리가 시작하기 전에 : 예, MP는 나쁜 관행으로 간주됩니다. evil eval

, 명령 프로그래밍, 가변 데이터 구조, 양방향 바인딩이므로 대기입니다.

이 중 하나를 사용하는 경우, 상당히 많은 사람들이 당신에게 무언가 잘못하고 있다고 말하는 것과 더 나은 조건에 맞게 변경되어야한다고 말하는 상당히 많은 사람들이있을 것입니다. 그러나 언제나 그렇듯이 다양한 도구와 기술이 사용 가능하며 특정 시나리오마다 적용 가능성이 다릅니다. 때때로, 극단적이거나 미쳤거나 단순히 나쁘게 보이는 것은 특정 상황에서 마지막 수단이 될 수 있습니다. 불행히도, 일부 관행은 나쁜 것으로 간주되므로 올바른 방식으로 잘못된 일을하는 방법을 설명하기 위해 많은 기사를 찾을 수 없습니다. 여기에 설명 된 상황은 부자연스럽고 가짜 위젯으로 극단으로 밀어서 선택을 보여줍니다. 그런 다음 독자로서 당신이 보는 것을 좋아하는지 결정해야합니다. 다른 것이 없다면,이 기사를 읽은 후에는 MP에 반대하기 위해 더 나은 이해를 얻게 될 것입니다.

원숭이 패치의 대상

우리 가이 기술을 더 깊이 파고 들기 전에 먼저 우리가 달성하고자하는 것을 확인합시다. 수정 된 위젯에는 코드 냄새가 있으며 이러한 문제를 해결하려고합니다. 하드 코딩 된 배경색 첫 번째는 ToggleError라는 메소드로 부울 매개 변수 에 따라 요소의 배경색을 변경해야합니다.

보시다시피, jQuery 메소드 CSS를 통해 배경색 속성을 설정합니다. 스타일 시트 규칙을 통해 지정하려고하기 때문에 이것은 문제입니다.

Nevil 콘솔 로그 위젯을 개발할 때는 콘솔 로그를 사용하여 현재 실행중인 개발자에게 프롬프트를 표시하십시오. 이것은 개발 중 좋은 접근법 일지 모르지만 생산 사용에서 가장 좋은 접근법은 아닙니다. 따라서 이러한 모든 디버그 문장을 제거하는 방법을 찾아야합니다.

블록 광고 서버 호출 위젯은 훌륭하지만 이상한 동작이 있습니다. 스크립트가 초기화 될 때마다 이상한 광고 서버에 요청하고 페이지에 불필요한 팽창 콘텐츠가 표시됩니다.

참고 : 데모 코드는 플러커에서 JSON 파일에 대한 나가는 AJAX 요청을 시뮬레이션하지만이를 이해하기를 바랍니다.

적용 범위 방법

MP의 주요 개념 중 하나는 기존 기능을 얻고 사용자 정의 동작을 사용하여 원래 코드를 호출하기 전 또는 후에 향상시키는 것입니다. 그러나 원래 구현을 호출하는 것이 항상 필요한 것은 아닙니다. 때로는 사용자 지정 작업으로 바꾸고 싶기 때문입니다. 이 접근법은 하드 코딩 된 배경색 문제를 해결하는 데 도움이됩니다.

MP가 적용되는 위치를로드하고 원래 구현과 함께 제공해야합니다. 일반적으로, 당신은 가능한 한 목표에 가까운 변화를 얻기 위해 노력해야하지만, 목표의 구현은 시간이 지남에 따라 변할 수 있음을 기억하십시오. 이 예에서는 초기화와 MP가 Main.js를 파일로 이동합니다.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>
위젯 구현을 살펴보면 위젯의 루트로 피드백 상자 객체가 있음을 알 수 있습니다. 나중에 ToggleError 기능은 프로토 타입에서 구현됩니다.

javaScript는 런타임에 객체를 수정할 수있는 동적 언어이므로 ToggleError를 사용자 정의 메소드로 대체하는 것입니다. 주목해야 할 유일한 것은 서명 (이름과 전달 된 매개 변수)을 동일하게 유지하는 것입니다.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>

새로운 구현은 이제 주어진 요소에 오류 클래스를 추가하여 CSS를 통해 배경색을 설정할 수 있습니다.

향상 방법
<code class="language-javascript">FeedbackBox.prototype.init = function() {
  // 我们想要跳过的广告服务器调用
  $.ajax('vendor/service.json', {
    method: 'GET'
  }).then(function(data) {
    console.log("FeedbackBox: AdServer contacted");
  });

  ...
</code>

이전 예에서는 자체 방법을 제공하여 원래 구현을 무시하는 방법을 보았습니다. 반면, 콘솔 로그 처리는 특정 통화를 필터링하고이를 억제해야합니다. 성공의 핵심은 포함 된 코드를 검사하고 워크 플로우를 이해하려고 노력하는 것입니다. 일반적으로 이는 선택한 브라우저에서 개발자 콘솔을 시작하고로드 된 리소스를 엿보기, 중단 점을 추가하고 객체 코드 섹션을 디버깅하여 기능을 이해함으로써 수행됩니다. 그러나 이번에는 다른 탭에서 벤더/jquery.feedbackbox.js라는 플 랭커 예제에서 구현을 열어야합니다.

디버그 메시지를 살펴보면 각각이

피드백 박스로 시작한다는 것을 알 수 있습니다. 따라서 우리가 원하는 것을 달성하는 쉬운 방법은 원래 통화를 가로 채고 작성할 제공된 텍스트를 확인한 다음 디버그 프롬프트가 포함되지 않은 경우에만 원래 메소드를 호출하는 것입니다. 이렇게하려면 먼저 원래 콘솔을 저장하겠습니다. 그런 다음, 우리는 사용자 정의 구현으로 원래 구현을 대체하여 제공된 속성 텍스트가 문자열 유형인지 먼저 확인하고, 그렇다면 Substring FeedbackBox를 포함하는지 확인합니다. 그렇다면 우리는 아무것도하지 않을 것입니다. 그렇지 않으면 적용 메소드를 호출하여 원래 콘솔 코드를 실행합니다. 이 메소드는 컨텍스트를 첫 번째 매개 변수로 사용합니다. 즉, 메소드가 해당 객체에서 호출되어야하며 마법의 인수 변수를 호출해야합니다. 후자는 원래 원래 Console.log Call에 전달 된 모든 매개 변수의 배열입니다.

참고 : 왜 우리가 단순히 텍스트 속성을 전달하지 않았는지 궁금 할 것입니다. 음, Console.log는 실제로 무한 매개 변수로 호출 할 수 있으며 결국 단일 텍스트 출력에 연결됩니다. 따라서 이러한 모든 매개 변수를 정의하는 대신 (무한한 가능성에 매우 어려울 수 있음), 우리는 모든 들어오는 컨텐츠를 전달합니다.

intercept ajax 호출

마지막으로, 광고 서버 문제를 해결하는 방법을 살펴 보겠습니다. 위젯의 init 함수를 다시 살펴 보겠습니다 :

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>
첫 번째 아이디어는 브라우저를 열고 jQuery 플러그인을 무시하는 방법을 검색하는 것입니다. 검색 기술이 얼마나 좋은지에 따라 정답을 찾거나 찾지 못할 수도 있습니다. 그러나 멈추고 여기서 무슨 일이 일어나고 있는지 생각해 봅시다. jQuery가 Ajax 방법에 무엇을하든, 어느 시점에서 기본 XMLHTTPREQUEST를 만듭니다.

무대 뒤에서 어떻게 작동하는지 봅시다. MDN에서 발견 된 가장 간단한 예는 다음을 보여줍니다.

우리는 새로운 xmlhttprequest 인스턴스가 생성 된 것을 볼 수 있습니다. 그것은 우리가 실제로 신경 쓰지 않는 OnreadyStateChange 메소드와 개방 및 전송 방법을 가지고 있습니다. 매우 좋은. 따라서 우리의 아이디어는 보내기 메소드를 패치하고 특정 URL에 대한 통화를 수행하지 말라고 지시하는 것입니다.

좋아, 객체 자체에서 대상 URL을 얻을 수 없다는 것이 밝혀졌습니다. 죄송합니다. 그러면 우리는 무엇을해야합니까? 우리는 그것을 물체에 올려 놓았습니다. URL을 얻을 수있는 첫 번째 기회를 찾고, Open 메소드가이를 두 번째 매개 변수로 받아 들인다는 것을 알 수 있습니다. 객체 자체에서 URL을 사용할 수 있도록 MP Open 메소드부터 시작하겠습니다.
<code class="language-javascript">FeedbackBox.prototype.init = function() {
  // 我们想要跳过的广告服务器调用
  $.ajax('vendor/service.json', {
    method: 'GET'
  }).then(function(data) {
    console.log("FeedbackBox: AdServer contacted");
  });

  ...
</code>
이전과 마찬가지로, 우리는 나중에 사용하기 위해 원래 오픈 메소드를 변수에 저장합니다. 그런 다음 사용자 정의 구현으로 원래 구현을 무시합니다. JavaScript (동적 언어)를 사용할 수 있으므로 언제든지 새 속성을 생성하고 이름을 _URL로 이름을 지정할 수 있습니다.

이 외에도 다른 작업을 수행하지 않고 원래 열린 메소드를 호출합니다.
<code class="language-javascript">function FeedbackBox(elem, options) {
  this.options = options;  
  this.element = elem;  
  this.isOpen = false;
}

FeedbackBox.prototype.toggleError = function(obj, isError) {
  ...
}</code>
Send MP를 다시 방문하면 조건 검사를 해결하는 방법이 분명합니다. 다음은 수정 된 버전입니다

결론

여기서 보는 것은 원숭이 패치를 사용하여 런타임시 코드의 동작을 변경하는 것에 대한 간략한 소개입니다. 그러나 더 중요한 것은이 게시물이 원숭이 패치를 다루는 방법에 대한 아이디어를 제공하기를 바랍니다. 패치 자체는 일반적으로 간단하지만 런타임에 코드를 조정하는 방법에 대한 아이디어를 갖는 것이 중요합니다.

또한, 원숭이 패치에 대해 어떻게 생각하든 동적 언어를 사용하는 것의 아름다움을 볼 수있는 기회가 있기를 바랍니다.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.addClass("error");
  } else {
    obj.removeClass("error");
  }
};</code>
실용 원숭이 패치 (FAQ)에 대한 FAQ JavaScript에서 원숭이 패치의 개념은 무엇입니까?

JavaScript의 원숭이 패치는 내장 또는 사용자 정의 객체의 동작이 일반적으로 객체의 프로토 타입을 추가, 수정 또는 변경하여 수정되는 기술입니다. 이것은 원래 소스 코드를 변경하지 않고 코드의 동작을 확장하거나 변경하는 방법입니다. 이 기술은 수리를 구현하고 기존 기능을 향상 시키며 테스트 및 디버깅 목적으로도 사용될 수 있습니다.

JavaScript와 Python의 원숭이 패치의 차이점은 무엇입니까?

JavaScript와 Python의 원숭이 패치의 개념은 동일하지만 객체를 수정하거나 확장하는 동작 - 구현은 언어 자체의 차이로 인해 다릅니다. JavaScript에서 원숭이 패치는 일반적으로 물체의 프로토 타입을 수정하여 수행되는 반면, 파이썬에서는 클래스 또는 인스턴스 방법을 추가하거나 변경하여 수행됩니다. 두 언어의 유연성은 원숭이 패치를 허용하지만,이 기술은 예상치 못한 행동을 피하기 위해주의해서 사용해야합니다.

원숭이 패치가 JavaScript에서 모범 사례로 간주됩니까?

원숭이 패치는 강력한 도구이지만 논란이없는 것은 아닙니다. 원래 소스 코드를 변경하지 않고도 기능을 신속하게 수정하거나 확장 할 수 있지만, 특히 남용하거나 부적절한 경우 예측할 수없는 행동과 충돌로 이어질 수 있습니다. 따라서주의와 책임이있는 원숭이 패치를 사용하는 것이 좋습니다. 항상 전체 코드 기반에 잠재적 인 영향을 고려합니다.

원숭이 패치의 잠재적 위험은 무엇입니까?

원숭이 패치의 주요 위험은 코드에서 예측할 수없는 행동과 충돌로 이어질 수 있다는 것입니다. 기존 객체의 동작을 수정하기 때문에 코드 기반의 다른 곳에서 패치 된 메소드를 사용하면 코드를 중단 할 수 있습니다. 또한 수정을 알지 못하는 다른 개발자들 사이에서 혼란을 일으킬 수 있습니다. 따라서 원숭이 패치를 명확하고 포괄적으로 기록하는 것이 중요합니다.

JavaScript에서 함수를 깨끗하게 패치하는 방법은 무엇입니까?

JavaScript의 함수를 깨끗하게 패치하려면 원래 함수 주변에 래퍼를 만들 수 있습니다. 이 래퍼 함수는 원래 기능을 호출 한 다음 필요에 따라 동작을 추가하거나 수정합니다. 이런 식으로 원래의 기능은 변경되지 않고 추가 동작이 명확하게 분리되어 코드를 이해하고 유지 관리하기 쉽게 만듭니다.

원숭이 패치를 테스트 및 디버깅에 사용할 수 있습니까?

예, 원숭이 패치는 테스트 및 디버깅에 유용한 도구로 사용될 수 있습니다. 함수 또는 메소드의 동작을 수정하거나 확장하면 다른 시나리오를 시뮬레이션하거나 오류를 주입하거나 로그를 추가하여 코드 실행을 추적 할 수 있습니다. 그러나 예상치 못한 부작용을 피하기 위해 생산 코드에서 이러한 패치를 제거하거나 분리하는 것이 중요합니다.

JavaScript의 원숭이 패치에서 프로토 타입은 어떤 역할을합니까?

JavaScript에서 프로토 타입은 원숭이 패치에서 중요한 역할을합니다. JavaScript는 프로토 타입 기반 언어이므로 각 객체에는 속성과 메소드를 상속하는 프로토 타입이 있습니다. 객체의 프로토 타입을 수정하면 해당 객체의 모든 인스턴스의 동작을 변경할 수 있습니다. 이것은 JavaScript의 원숭이 패치의 기초입니다.

원숭이 패치는 JavaScript의 성능에 어떤 영향을 미칩니 까?

JavaScript 성능에 대한 원숭이 패치의 영향은 일반적으로 적습니다. 그러나 원숭이 패치의 과도하거나 부적절한 사용은 성능 문제를 유발할 수 있습니다. 예를 들어, 코드에서 패치 된 메소드를 자주 사용하면 추가 동작이 실행 속도가 느려질 수 있습니다. 따라서주의를 기울여 원숭이 패치를 사용하고 정기적으로 성능을 모니터링하십시오.

원숭이 패치를 사용하여 내장 JavaScript 객체를 확장 할 수 있습니까?

예, 원숭이 패치는 내장 JavaScript 객체를 확장하는 데 사용될 수 있습니다. 내장 객체의 프로토 타입을 수정하면 객체의 모든 인스턴스에 사용할 수있는 새로운 메소드 또는 속성을 추가 할 수 있습니다. 그러나 이것은 동일한 방법이나 속성을 도입 할 수있는 미래 버전의 JavaScript와의 충돌을 피하기 위해주의해서 수행해야합니다.

JavaScript에서 원숭이 패치에 대한 대안은 무엇입니까?

JavaScript에는 원숭이 패치에 대한 몇 가지 대안이 있습니다. 일반적인 방법은 원래 객체를 포함하는 새 개체를 만들고 동작을 추가하거나 덮어 쓰는 조합을 사용하는 것입니다. 또 다른 방법은 상속을 사용하는 것입니다. 여기서 원래 클래스에서 물려 받고 메소드를 덮어 쓰는 새 클래스를 생성하는 것입니다. 이러한 방법은 원숭이 패치와 유사한 유연성을 제공 할 수 있지만 캡슐화가 향상되고 충돌 위험이 줄어 듭니다.

위 내용은 JavaScript에서 원숭이 패치의 실용적인 사용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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