簡體   English   中英

如何在函數中的javascript中創建2` this`引用

[英]How to create 2 `this` reference in javascript from within a function

我有問題讓我的代碼工作,因為我試圖將其分解為更小的方法因為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();

我還想避免使用es6的arrow-functions () =>self = this技術,如果可能的話,如YDKJS:This&Object Prototypes中推薦的那樣

有沒有一種方法來.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

如何訪問正確的this回調里面? 正如@gyre在下面的評論中所提出的,提供了如何控制this詳細信息,但根本沒有提到event.target 無論如何,這里是Event.target上的MDN Docs

您可以使用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); 
})

只需轉換舊樣式並將其設置為其他內容。

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

你會經常遇到這個和類似的問題。 根據需要,我可以通過兩種方式解決它:使用閉包或綁定。

使用閉包在像你這樣的情況下工作得很好,你在這里設置一個事件並在同一個父函數中定義事件處理程序。 您可以利用子函數可以訪問父函數變量並訪問屏蔽形式的事實

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

另一種方法使用bind。 當你想在一個函數中設置一個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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM