2017-02-28 83 views
4

我有問題讓我的代碼工作,因爲我試圖將它分解成更小的方法,因爲this引用。我的代碼如下:如何在函數內創建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技術如果可能的話。

有一種方法來.bind()/.call()/.apply()方法onChange()引用this,其引用到pageObj,並且還向無線輸入this,其引用?

如有必要,請隨意重新排列代碼。謝謝,期待!

更新

由於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); 

     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?由@gyre在下面的意見建議提供瞭如何控制this但未提及的詳細信息event.target。無論如何,這裏是MDN Docs on Event.target

+1

的可能的複製[?如何訪問正確的\'這\'回調內(http://stackoverflow.com/questions/20279484 /如何訪問正確的回調內部) – gyre

回答

2

只是去舊風格,並將其設置爲別的東西。

 
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(); 

在你不需要的方式使用this事件處理程序內部的特定情況下,你可以有一個事件參數和使用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

這裏的'更進一步...'代碼也是這個問題的一個工作答案,因爲它是一個完整的答案,而不是按照問題中所述使用es6的雙箭頭功能。標記爲答案! –

3

您可以使用event.targetevent.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

你會偶爾遇到這個和類似的問題。根據需要,我可以用以下兩種方法之一來解決問題:使用閉合或綁定。

使用閉包在像你這樣的情況下工作得很好,你可以在這裏設置一個事件並在同一個父函數中定義事件處理函數。你可以利用這一事實的子函數可以訪問父函數變量優勢和訪問一個蒙面的形式這

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(); 

另一種方法是使用綁定。當你想在一個函數中設置一個eventListener時,這個函數特別有用,該函數調用在其他地方定義的處理函數,但需要設置監聽器的函數的'this'上下文中的信息。它可以用它將代碼分解成更小的函數。

使用你的例子可能看起來像這樣的例子:

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

關閉方法與嘗試設置詞法「這個」相同。我將親自使用'.bind()'作爲[YDKJS]中的引用(https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object %20prototypes/ch2.md#lexical-this):_「儘管self = this和arrow函數似乎都是不錯的」解決方案「,不想使用bind(..),但它們實際上是從這個而不是理解和逃避擁抱它。「_。但是,它也可能是一個偏好和一致性的問題,所以...很好的答案,謝謝! –