2017-02-28 1 views
4

this 참조 때문에 더 작은 방법으로 분해하려고 할 때 코드가 작동하는 데 문제가 있습니다. 내 코드는 다음과 같다 :함수 내에서 javacript에서 2`this` 참조를 만드는 방법

const pageObject = { 

    /* set listener to get id of the radio input and then do something with it*/ 
    onChange() { 

     // `this` here refers to the pageObject 
     console.log(this); 

     $('.radio input[type="radio"]').on('click', function() { 

       // `this` here refers to the radio input 
       console.log(this); 

       let $id = $(this).data('id'); 

       // Error because `this` is referencing the radio input and not the pageObject. 
       this.doSomething($id); 
     } 

    }, 

    /* just does something */ 
    doSomething($id) { 
     return ... 
    } 

} 

// just calls the method on object so we can get started 
pageObject.onChange(); 

는 또한 YDKJS: This & Object Prototypes에서 권고 ES6의 화살표 기능 () =>self = this 기술을 가능하면 사용하지 않도록합니다.

또한 pageObj하고 무선으로 입력되는 참조 thisthis하는 참조를 참조 .bind()/.call()/.apply()있어서 onChange()하는 방법이 있는가?

필요에 따라 코드를 자유롭게 조정하십시오. 고마워, 앞으로! 아래의 코멘트에 @gyre에 의해 제안

const pageObject = { 

    /* set listener to get id of the radio input and then do something with it*/ 
    onChange() { 

     // `this` here refers to the pageObject 
     console.log(this); 

     let radioHandler = function radioHandler(event) { 

       // `this` here also refers to the pageObject too since we are about to call this function via .bind() 
       console.log(this); 

       // use event.target here instead. sweet stuff. 
       let $id = $(event.target).data('id'); 

       // doSomething() now works! 
       this.doSomething($id); 
     } 

     $('.radio input[type="radio"]').on('click', radioHandler.bind(this)); 

    }, 

    /* just does something */ 
    doSomething($id) { 
     return ... 
    } 

} 

// just calls the method on object so we can get started 
pageObject.onChange(); 

업데이트 2

How to access the correct this inside a callback? : event.target

업데이트

덕분에 여기 아래에 제안 작업 코드 블록으로 this을 제어하는 ​​방법에 대한 훌륭한 세부 정보를 제공하지만은 언급하지 않습니다. 0. 어쨌든, 여기에 MDN Docs on Event.target

+1

가능한 복제 [? 콜백 내에서 올바른 \ '이 \를'에 액세스하는 방법 (http://stackoverflow.com/questions/20279484/올바른 방법 -이 - 콜백 내부) – gyre

답변

2

그냥 이전 스타일로 이동하여 다른 것으로 설정하십시오. 당신이 방법으로 이벤트 핸들러 내부 this를 사용할 필요가 없습니다 특정 경우

 
const pageObject = { 

    /* set listener to get id of the radio input and then do something with it*/ 
    onChange() { 

     // `this` here refers to the pageObject 
     console.log(this); 
     const self = this; 

     $('.radio input[type="radio"]').on('click', function() { 

       // `this` here refers to the radio input 
       console.log(this); 

       let $id = $(this).data('id'); 

       // Error because `this` is referencing the radio input and not the pageObject. 
       self.doSomething($id); 
     }; 

    }, 

    /* just does something */ 
    doSomething($id) { 
     return ... 
    } 

} 

// just calls the method on object so we can get started 
pageObject.onChange(); 

, 당신은 이벤트 매개 변수를 가질 수 있고 같은 event.target을 사용하더라도 더

 
const pageObject = { 

    /* set listener to get id of the radio input and then do something with it*/ 
    onChange() { 

     // `this` here refers to the pageObject 
     console.log(this); 

     $('.radio input[type="radio"]').on('click', (event) => { 

       // `this` here refers to the radio input 
       console.log(event.target); 

       let $id = $(event.target).data('id'); 

       // Error because `this` is referencing the radio input and not the pageObject. 
       this.doSomething($id); 
     }; 

    }, 

    /* just does something */ 
    doSomething($id) { 
     return ... 
    } 

} 

// just calls the method on object so we can get started 
pageObject.onChange(); 

..

 
const pageObject = { 

    /* set listener to get id of the radio input and then do something with it*/ 
    onChange() { 

     // `this` here refers to the pageObject 
     console.log(this); 

     $('.radio input[type="radio"]').on('click', this.onRadioClick.bind(this)) ; 

    }, 

    onRadioClick(event) { 

      // `this` here refers to the radio input 
      console.log(event.target); 

      let $id = $(event.target).data('id'); 

      // Error because `this` is referencing the radio input and not the pageObject. 
      this.doSomething($id); 
    }, 

    /* just does something */ 
    doSomething($id) { 
     return ... 
    } 

} 

// just calls the method on object so we can get started 
pageObject.onChange(); 
+1

'Even further ...'코드는 완전한 대답이기 때문에이 질문에 대한 답변입니다. 질문에 언급 된 것처럼 es6의 양방향 화살표 기능을 사용하십시오. 답변으로 표시되었습니다. –

3

event.target 또는 event.currentTarget을 사용할 수 있습니다. 참조 이벤트 이벤트가 전달됩니다. javascript) (전화 : .on())으로 마감됩니다.

$('.radio input[type="radio"]').on('click', function(event) { 

    // `this` here refers to the radio input 
    let $id = $(event.target).data('radioId'); 

    // Error because `this` is referencing the radio input and not the pageObject. 
    this.doSomething($id); 
}) 
+0

덕분에 올바른 방향으로 나를 안내 할 수있었습니다. 이 코드는 여전히 라디오 입력을 가리키고 있기 때문에 여전히 오류가 발생합니다. 나는 실무 답변을 포함하도록 내 질문을 업데이트했습니다. –

+0

핸들러 안에서'this '를'.on()'에 전달할 수 있습니다. 핸들러 안에서'event.data'를 사용하여'this'를 참조하십시오 :'pageObject'' .on ("click", {pageObject : this}, function (event) {console.log (event.data.pageObject)})'. 자신의 답변을 게시하고 수락 할 수 있습니다. http://stackoverflow.com/help/self-answer – guest271314

1

당신은 이와 비슷한 문제를 자주 접하게 될 것입니다. 필요에 따라, 나는 closure 나 binding을 사용하는 두 가지 방법 중 하나로 해결한다.

클로저를 사용하면 이벤트를 설정하고 동일한 상위 함수에서 이벤트 처리기를 정의하는 여기에서와 같이 잘 작동합니다. 당신은 하위 기능은 부모 함수의 변수에 액세스 할 수있는 사실을 활용이

const pageObject = { 

    /* set listener to get id of the radio input and then do something with it*/ 
    onChange() { 

     const parent = this 
     // 'parent and `this` here both refer to the pageObject 
     // 'parent' masks an instance of 'this' which can be accessed via closures 
     console.log('parent, this: ', parent, this); 

     $('.radio input[type="radio"]').on('click', function() { 

      // `this` here refers to the radio input 
      console.log(this); 

      let $id = $(this).data('id'); 

      // 'parent' accesses parent 'this' thanks to closures and masking 
      parent.doSomething($id); 
     } 

    }, 

    /* just does something */ 
    doSomething($id) { 
     return ... 
    } 

} 

// just calls the method on object so we can get started 
pageObject.onChange(); 

또 다른 방법은 바인딩을 사용 의 마스크 형태에 액세스 할 수 있습니다. 이는 다른 곳에서 정의 된 핸들러 함수를 호출하지만 리스너를 설정하는 함수의 'this'컨텍스트로부터 정보가 필요한 한 함수에서 eventListener를 설정하려는 경우에 특히 유용합니다. 코드를 사용하여 코드를 작은 기능으로 분해 할 수 있습니다.

같은 것을 볼 수 있었다 귀하의 예제를 사용하여 예 :

const pageObject = { 

    /* set listener to get id of the radio input and then do something with it*/ 
    onChange() { 

     // `this` refers to the pageObject 
     console.log(this); 

     // creates radio onClick eventListener 
     // assigns handleRadio function as event handler 
     // binds pageObject 'this' context for use in event handler 
     $('.radio input[type="radio"]').on('click', this.handleRadio).bind(this); 
    }, 

    // separated event handler function to show how this works in more modular code. 
    handleRadio(e) { 
     // use e.target to give you the context for the click event 
     // use 'this' to access the pageObject 'this' context 
     console.log('e.target, this: ', e.target, this); 

     // still accesses pageObject 'this' due to the eventListener bind 
     let $id = $(this).data('id'); 

     // No error 
     this.doSomething($id); 
    }, 

/* just does something */ 
doSomething($id) { 
    return ... 
} 

} 

// just calls the method on object so we can get started 
pageObject.onChange(); 
+0

클로저 방법은 어휘'this '를 설정하는 것과 같습니다. 저는 지금 [YDKJS] (https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object)에 인용 된 것처럼'.bind()'를 개인적으로 고수 할 것입니다. % 20prototypes/ch2.md # lexical-this) : _ "self = this와 arrow-functions는 모두 bind (..)를 사용하지 않으려 고하는 좋은"솔루션 "처럼 보일 수 있지만, 이해와 이해 대신 본질적으로 빠져 나옵니다. 그것을 받아 들인다. "_. 하지만 다시 한번, 선호도와 일관성의 문제 일 수도 있습니다. 그래서 ... 훌륭한 답변입니다, 감사합니다! –

관련 문제