2

I want to bind a function with specific arguments to an .onclick() in a context like this:

for(var i = 0; i < 3; i++) {
    for(var j = 0; j < 3; j++) {
        var button = document.createElement("button");
        button.textContent = board[i][j];
        button.onclick = function() {
            makeMove(i,j); //The function will always be called with the last value of i and j.
        }
        document.body.appendChild(button);
    }
}

I can solve this by using makeMove.bind(null,i,j) or function(arg1,arg2){ return function() { makeMove(i,j); }}(i,j) but both does not seem right because Function.prototype.bind() was created to bind a context to this and I don't want to use IIFE because it is a TicTacToe example for beginner programmers.

Is there another way to solve this problem without much complexity?

Joshua Kleveter
  • 1,769
  • 17
  • 23

1 Answers1

1

Change var to let. let introduces a different scoping mechanism then the traditional functional scope of Javascript. The let statement declares a block scope local variable. The let statment would let the onclick function handler to refer to 3 different instances of the variable i and similary 3 different variables for j.

for(let i = 0; i < 3; i++) {
    for(let j = 0; j < 3; j++) {
        var button = document.createElement("button");
        button.textContent = board[i][j];
        button.onclick = function() {
        makeMove(i,j); //The function will always be called with the last value of i and j.
    }
        document.body.appendChild(button);
    }
}

Complete Working version (Replaced board content with static text "X")

for(let i = 0; i < 3; i++) {
    for(let j = 0; j < 3; j++) {
        var button = document.createElement("button");
        button.textContent = "x";
        button.onclick = function() {
            makeMove(i,j); //The function will always be called with the last value of i and j.
        }
        document.body.appendChild(button);
    }
}

function  makeMove(i,j){
console.log("i= " + i + "--- j=" + j);
}
Abhinav Galodha
  • 9,293
  • 2
  • 31
  • 41