jQuery의 $ .proxy () 이해


167

에서 문서 나는 이해 .proxy()인수로 전달하는 기능의 범위를 변경합니다. 누군가 나에게 이것을 더 잘 설명해 주시겠습니까? 왜 이렇게해야합니까?


1
문서에 따르면 "이 메소드는 컨텍스트가 다른 객체를 다시 가리키는 요소에 이벤트 핸들러를 연결하는 데 가장 유용합니다. 또한 jQuery는 jQuery.proxy ()에서 반환 된 함수를 바인딩하더라도 "원본을 통과 한 경우 여전히 올바른 기능을 바인드 해제하십시오." 부족한 구절에 대해 특별한 점이 있습니까?
bzlm

1
또한 jQuery는 jQuery.proxy ()에서 반환 된 함수를 바인딩하더라도 원본을 전달한 경우에도 여전히 올바른 함수를 바인딩 해제합니다. "
Aditya Shukla

원래는 프록시가 작성된 것입니다. 그러나이 물건을 완전히 파악하지 못했기 때문에 사용해야합니까?
bzlm

1
다음은 nettuts의 $ .proxy 작동 방식을 보여주는 훌륭한 비디오 자습서입니다. http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-learning-jquery-1-4s-proxy/
후세인

1
@bzlm,이 방법을 사용할 때 jquery 설명서를 읽고있었습니다.
Aditya Shukla

답변:


381

그것이 궁극적으로하는 것은 this함수의 가치가 원하는 가치가되도록하는 것입니다.

일반적인 예는 핸들러 setTimeout내에서 발생하는 것 click입니다.

이것을 가지고 :

$('#myElement').click(function() {
        // In this function, "this" is our DOM element.
    $(this).addClass('aNewClass');
});

의도는 간단합니다. 때 myElement클릭하면, 클래스를 얻어야한다 aNewClass. 핸들러 내부 this는 클릭 된 요소를 나타냅니다.

그러나 수업을 추가하기 전에 짧은 지연을 원한다면 어떻게해야합니까? 우리는 setTimeout그것을 달성하기 위해 a 를 사용할 수도 있지만 문제는 우리가주는 기능에 관계없이 그 함수 내부 setTimeout의 가치가 요소 this가 아니라는 것 window입니다.

$('#myElement').click(function() {
    setTimeout(function() {
          // Problem! In this function "this" is not our element!
        $(this).addClass('aNewClass');
    }, 1000);
});

대신 우리가 할 수있는 것은를 호출 $.proxy()하여 함수와 할당하려는 값을 보내면 this해당 값을 유지하는 함수를 반환합니다.

$('#myElement').click(function() {
   // ------------------v--------give $.proxy our function,
    setTimeout($.proxy(function() {
        $(this).addClass('aNewClass');  // Now "this" is again our element
    }, this), 1000);
   // ---^--------------and tell it that we want our DOM element to be the
   //                      value of "this" in the function
});

따라서 $.proxy()함수와 원하는 값 을 제공 한 후 제대로 설정 this되었는지 확인하는 함수를 반환했습니다 this.

어떻게합니까? 메소드를 사용하여 함수를 호출 하는 익명 함수를 반환 .apply()하므로 명시 적으로의 값을 설정할 수 있습니다 this.

반환되는 함수를 간단히 보면 다음과 같습니다.

function() {
    // v--------func is the function we gave to $.proxy
    func.apply( ctx );
    // ----------^------ ctx is the value we wanted for "this" (our DOM element)
}

따라서이 익명 함수는에 주어지며 setTimeout모든 기능은 올바른 this컨텍스트로 원래 함수를 실행하는 것 입니다.


$.proxy(function () {...}, this)오히려 사용 하는 것의 가치는 무엇입니까 (function() {...}).call(this)? 차이가 있습니까?
저스틴 모건

11
@ 저스틴 모건 : .call당신 과 함께 즉시 함수를 호출합니다. 를 사용하면 새 함수를 반환하는 위치 $.proxy와 같습니다 Function.prototype.bind. 즉, 새로운 기능은이 this때문에이 전달되는 경우, 영구적으로 결합 된 값을 setTimeout, 그리고 setTimeout여전히 올바른 것, 기능 나중에 호출 this값입니다.
회색 상태가

2
이 기술의 장점이 있다면 무엇입니까? $ ( '# myElement'). click (function () {var el = $ (this); setTimeout (function () {el.addClass ( 'aNewClass');}, 1000);});
Greg

1
이 예제에서는 $ .proxy 메소드를 사용할 필요가 없습니다. 대신 $ ( '# myElement'). click (function () {var that = this; setTimeout (function () {/ / 핸들러 메소드의 범위에서 선언 된 변수를 통한 새로운 컨텍스트 $ (that) .addClass ( 'aNewClass');}, 1000);});
paul

4
112k 응답, 무서운 JavaScript / jQuery 지식을 가진 익명의 사용자이며 2011 년 10 월 이후로 보지 못한 ... John Resig?
cantera

49

더 세부로하지 않고 (이 대략 때문에 필요한 것이다 컨텍스트 인 ECMAScript에서, 이 컨텍스트 변수 등)

ECMA- / Javascript에는 세 가지 유형의 "컨텍스트"가 있습니다.

  • 세계적인 맥락
  • 기능 문맥
  • 평가 컨텍스트

모든 코드는 실행 컨텍스트 에서 실행됩니다 . 이 하나의 글로벌 컨텍스트 및 기능 (및 평가) 컨텍스트의 많은 경우가있을 수 있습니다. 이제 흥미로운 부분 :

함수의 모든 호출은 함수 실행 컨텍스트에 들어갑니다. 함수의 실행 컨텍스트는 다음과 같습니다.

활성화 오브젝트
범위 체인
이 값

그렇게 값은 실행 컨텍스트와 관련되는 특수 객체입니다. ECMA- / Javascript 에는 함수 실행 컨텍스트 에서이 값을 변경할 수있는 두 가지 함수가 있습니다 .

.call()
.apply()

함수 foobar()가 있으면 다음 을 호출 하여이 값을 변경할 수 있습니다 .

foobar.call({test: 5});

이제 foobar전달한 객체에 액세스 할 수 있습니다 .

function foobar() { 
    this.test // === 5
}

이것은 정확히 무엇입니까 jQuery.proxy(). functionand context(객체 이외의 다른 것)를 취하고 .call()또는 호출하여 함수를 연결하고 .apply()새 함수를 반환합니다.


1
우수한 설명, 단순 / 더 나은 기능에 대한 공식 jQuery를 워드 프로세서에 비해
higuaro

4

이 기능을 작성했습니다.

function my_proxy (func,obj)
{
    if (typeof(func)!="function")
        return;

    // If obj is empty or another set another object 
    if (!obj) obj=this;

    return function () { return func.apply(obj,arguments); }
}

1

"즉시 호출 된 함수 표현식, 짧은 : IIFE" 자체 실행 함수를 사용하여 동일한 목표를 달성 할 수 있습니다 .

    $('#myElement').click(function() {  
      (function(el){
         setTimeout(function() {
              // Problem! In this function "this" is not our element!
            el.addClass('colorme');
        }, 1000);
      })($(this)); // self executing function   
    });
.colorme{
  color:red;
  font-size:20px;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

  <div id="myElement">Click me</div>
</body>
</html>


2
이를 일반적으로 "자체 실행 함수"가 아닌 "IIFE (즉시 호출 함수 표현식)"라고합니다 . en.wikipedia.org/wiki/Immediately-invoked_function_expression을 참조하십시오 .
Chris Seed
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.