bindメソッド


bindメソッド

.bind.callと同様に、パラメータとバインドされますが、すぐに実行するのではなく、バインドされた関数を返します.
1番目のパラメータはthisを渡し、2番目のパラメータから必要なパラメータを渡します.
fn.bind(this, 인자1, 인자2, ...)
callやapplyに比べてbindには役に立つ使い方がたくさんあります.まず2つの例を見てみましょう.

Case 1:イベントハンドラ


bindは、イベントハンドラがイベントオブジェクトではなく別の値を渡す場合に便利です.以下の状況を仮定してみましょう.
<button id="btn">클릭하세요</button>
let btn = document.querySelector('#btn')
btn.onclick = handleClick

function handleClick() {
  console.log(this)
}

n.問題


上記の例
  • では、handleClickで見た値は何ですか.
  • 上記の例では、bindを使用してthisを変更する方法について説明します.
    let btn = document.querySelector('#btn')
    // 추후 이벤트에 의해 불리게 될 함수에서, this는 {hello: 'world'}가 됩니다.
    btn.onclick = handleClick.bind({ hello: 'world'})
    
    function handleClick() {
      console.log(this)
    }
    もっと役に立つ例を見てみましょう.複数のボタンを動的に作成し、イベントハンドラごとに異なる値をバインドする必要がある場合は、を考慮します.(Twitter sprintで似たような実装を体験したことがあるかもしれません.)
    次の例では、各ボタンをクリックすると、コンソールに名前が表示されます.

    より役に立つ例

    <div id="target"></div>
    let target = document.querySelector('#target')
    let users = ['김코딩', '박해커', '최초보']
    
    users.forEach(function(user) {
      let btn = document.createElement('button')
      btn.textContent = user
      btn.onclick = handleClick
      target.appendChild(btn)
    });
      
      
    function handleClick() {
      console.log(this)
    }
    上記のコードを作成した場合、コンソールで動的に生成された各ボタンをクリックすると、ボタンエンティティ自体が表示されます.この場合bindを使用して出力したい値をthisに渡したり、パラメータとして送信したりすることができます.

    Solution 1:

    let target = document.querySelector('#target')
    let users = ['김코딩', '박해커', '최초보']
    
    users.forEach(function(user) {
      let btn = document.createElement('button')
      btn.textContent = user
      btn.onclick = handleClick.bind(user) // 이렇게 바꿔볼 수 있습니다.
      target.appendChild(btn)
    });
      
      
    function handleClick() {
      console.log(this)
    }

    Solution 2:

    let target = document.querySelector('#target')
    let users = ['김코딩', '박해커', '최초보']
    
    users.forEach(function(user) {
      let btn = document.createElement('button')
      btn.textContent = user
      btn.onclick = handleClick.bind(null, user) // 굳이 this를 이용하지 않더라도 인자로 넘길 수도 있습니다.
      target.appendChild(btn)
    });
      
      
    function handleClick(user) {
      console.log(user)
    }
    bindではなく匿名関数を使用して問題を解決することもできます.

    Solution 3:

    let target = document.querySelector('#target')
    let users = ['김코딩', '박해커', '최초보']
    
    users.forEach(function(user) {
      let btn = document.createElement('button')
      btn.textContent = user
      btn.onclick = function() {
        handleClick(user)
      }
      target.appendChild(btn)
    });
      
      
    function handleClick(user) {
      console.log(user)
    }

    case 2: setTimeout


    settimeoutは、時間遅延が発生した後に関数を非同期で実行できる関数です.この関数には、ウィンドウオブジェクトを常に明確にバインドする機能があります.そのため、次のような場合があります.

    class Rectangle {
      constructor(width, height) {
        this.width = width
        this.height = height
      }
      
      getArea() {
        return this.width * this.height
      }
    
      printArea() {
        console.log('사각형의 넓이는 ' + this.getArea() + ' 입니다')
      }
      
      printSync() {
        // 즉시 사각형의 넓이를 콘솔에 표시합니다
        this.printArea()
      }
      
      printAsync() {
        // 1초 후 사각형의 넓이를 콘솔에 표시합니다
        setTimeout(this.printArea, 2000)
      }
    }
    
    let box = new Rectangle(40, 20)
    box.printSync() // '사각형의 넓이는 800 입니다'
    box.printAsync() // 에러 발생!
    エラーは、これがRectangleのインスタンスではないことを示しています.
    Uncaught TypeError: this.getArea is not a function
        at printArea (<anonymous>:12:36)

    n.問題

  • の場合、この値はいくらですか?printArea関数のインポート部分にconsole.log(this)を追加し、直接チェックします.
  • bindを使用してこの問題を解決できます.printAsyncセクションを次のように変更します.

    Solution 1:

    printAsync() {
      // 1초 후 사각형의 넓이를 콘솔에 표시합니다
      setTimeout(this.printArea.bind(this), 2000)
    }
    匿名関数を使用する必要がある場合は、以下の内容を変更できますが、これは簡潔な方法ではありません.

    ソリューション2(推奨しない):

    printAsync() {
      // 1초 후 사각형의 넓이를 콘솔에 표시합니다
      let self = this
      setTimeout(function() {
        self.printArea()
      }, 2000)
    }
    矢印関数を入力します.次の例を示します.矢印関数のthisに何か違いがあるか知っていますか.

    Solution 3:

    printAsync() {
      // 1초 후 사각형의 넓이를 콘솔에 표시합니다
      setTimeout(() => {
        this.printArea()
      }, 2000)
    }