Getter Setter

howdy
12 Replies
brr
brrOP•3mo ago
I have an IIFE I was trying to access its var with another iife but you cant since it will return the copy so i changed from:
return {
status,
check
}
return {
status,
check
}
to:
return {
get status() {
return status
},

check
}
return {
get status() {
return status
},

check
}
I cant find online any doc about suing get with iife is this really the correct way to do this? also, now im getting the modified value not the original one, which is good : D
vince
vince•3mo ago
I don't do anything with JS other than presentational code so take what I say with a grain of salt: but this looks really hacky I'm sure there's a better design pattern like you hinted to but I'm not sure, just wanted to chime in haha
13eck
13eck•3mo ago
What are you trying to accomplish, exactly? If it's an IIFE then the function has been run and the status is set. If the status won't change then you won't need to do anything else for this to function. I feel like there's some very important information missing for us to even begin to help you. Also, in the future, please only send one message with all the information. Don't use the send button as your punctuation. Instead, use real punctuation marks (like ., ,, !, etc). If you're on desktop, hold SHIFT while hitting enter will insert a newline instead of sending the message.
brr
brrOP•3mo ago
I would have used something else too but for the assignment its tic tac toe and im supposed to use either factory functions or iife I have two separate IIFE, one called gameBoard The other is patternChecker This is my function in gameBoard:
function display() {
console.clear();
console.log(patternChecker.status);
console.table(board);
if (patternChecker.status) console.log("Someone won!");
};
function display() {
console.clear();
console.log(patternChecker.status);
console.table(board);
if (patternChecker.status) console.log("Someone won!");
};
I have to access status from patternChecker i will move to ui later, it is a console only game for now.
13eck
13eck•3mo ago
Ok, so the patternChecker.status is dynamic, then? If that's the case then yes a getter would be a good idea. What are the possible values for the status? It looks like a simple Boolean, but if there are two players then it should be a string, yeah? Or are you using the "empty string is a falsey value" to check? Also, what do your IIFEs look like? And why the preference? I find factory functions better and am interested in your opinion.
brr
brrOP•3mo ago
- It is a boolean - IIFE over factory functions as I do not need multiple instances, I would appreciate your opinion tho
const patternChecker = (() => {
let status = false;
const boardLength = gameBoard.board.length;

function check() {
checkRow();
checkColumn();
checkDiagonal();
if (status) {
gameLogic.updateState();

}
};

function allEqual(arr) {
return arr.every(x => x == arr[0] && (x == "X" || x == "O") && arr.length == 3);
}
function checkRow() {
for (let i = 0; i < boardLength; i++) {
const row = new Array();
for (let j = 0; j < boardLength; j++) {
row.push(gameBoard.board[i][j])
};
if (allEqual(row)) {
status = true;
};
}
}
function checkColumn() {
for (let i = 0; i < boardLength; i++) {
const column = new Array();
for (let j = 0; j < boardLength; j++) {
column.push(gameBoard.board[j][i])
};
if (allEqual(column)) {
status = true;
};
}
};

function checkDiagonal() {
const diagonal = new Array();
for (let i = 0; i < boardLength; i++) {
for (let j = 0; j < boardLength; j++) {
if (i == j) {
diagonal.push(gameBoard.board[i][j])
};
};
if (allEqual(diagonal)) {
status = true;
};
}
};

return {
get status() {
return status
},

check
}

})();
const patternChecker = (() => {
let status = false;
const boardLength = gameBoard.board.length;

function check() {
checkRow();
checkColumn();
checkDiagonal();
if (status) {
gameLogic.updateState();

}
};

function allEqual(arr) {
return arr.every(x => x == arr[0] && (x == "X" || x == "O") && arr.length == 3);
}
function checkRow() {
for (let i = 0; i < boardLength; i++) {
const row = new Array();
for (let j = 0; j < boardLength; j++) {
row.push(gameBoard.board[i][j])
};
if (allEqual(row)) {
status = true;
};
}
}
function checkColumn() {
for (let i = 0; i < boardLength; i++) {
const column = new Array();
for (let j = 0; j < boardLength; j++) {
column.push(gameBoard.board[j][i])
};
if (allEqual(column)) {
status = true;
};
}
};

function checkDiagonal() {
const diagonal = new Array();
for (let i = 0; i < boardLength; i++) {
for (let j = 0; j < boardLength; j++) {
if (i == j) {
diagonal.push(gameBoard.board[i][j])
};
};
if (allEqual(diagonal)) {
status = true;
};
}
};

return {
get status() {
return status
},

check
}

})();
I was tempted sorry so many lines 😅 I can put it on a pastebin site i bet this code can be more short way mroeeeeeeeeee
13eck
13eck•3mo ago
My two big reasons for factory functions, taking your case into account: * If you want to restart the game, just instantiate a new instance * You can pass in data to the function to use. Your boardLength is using gameBoard without it being passed in as args to the function. So it's a "magic variable" as you don't really know where it's coming from or if it even exists when the object is made
brr
brrOP•3mo ago
I will keep that in my mind Fair points
13eck
13eck•3mo ago
Another suggestion: instead of allEqual returning a Boolean, do the check twice—once for "X" and once for "O". And return the letter of whichever is all equal. Or return false or an empty string if neither pass. That way you can use status to output who won.
// from your `display()` function provided above
if (patternChecker.status) console.log(`${patternChecker.status} won!`);
// from your `display()` function provided above
if (patternChecker.status) console.log(`${patternChecker.status} won!`);
Now that I'm looking at it, a factory function won't do much for restarting your game, as that will be done in the gameBoard object. But I've always seen IIFEs as a hack around needing to define and then create the factory function. And factories are going to be a lot more useful later on with pretty much everything else, so I suggest sticking to that pattern so you won't have to "unlearn" using IIFEs. Also, looking at your code, you're also using gameLogic not passing it in in as an arg. In most code bases you'll want to pass in any outside data the object needs to do it's thing so you don't have to worry about proper naming, forgetting to instantiate, etc. Which is yet another reason to use a factory and not an IIFE.
brr
brrOP•3mo ago
Thanks for the insight @13eck.c I don't get the last point but i will read it again You messaged at the right time, I was planning to break down (split) the code further but now I will try implementing factory functions more
13eck
13eck•3mo ago
Last point is that gameLogic is being used and I'm assuming that it's another object being declared somewhere else. Best practice is to pass in any other objects being used as function arguments. That way you know where data is coming from and you don't need to worry about the object having a specific name. For example:
// object data omitted to showcase my point
const patternChecker = (gameLogic, boardData) => { };

const gameLogicDataIsHere = { };
const gameBoardData = { };
// note that the game logic and board data can be called anything.
// they just need to be passed into the function in the right order
const checkPattern = patternChecker(gameLogicDataIsHere, gameBoardData);
// object data omitted to showcase my point
const patternChecker = (gameLogic, boardData) => { };

const gameLogicDataIsHere = { };
const gameBoardData = { };
// note that the game logic and board data can be called anything.
// they just need to be passed into the function in the right order
const checkPattern = patternChecker(gameLogicDataIsHere, gameBoardData);
When you have the game ready to run I'd love to have a link to try it !
brr
brrOP•3mo ago
sure but i will share afte rmkaing the gui mate im so tired rn, i have messed up the really use of iife, its so messed up, the way im managing & exposing the vars
Your main goal here is to have as little global code as possible. Try tucking as much as you can inside factories. If you only need a single instance of something (e.g. the gameboard, the displayController etc.) then wrap the factory inside an IIFE (module pattern) so it cannot be reused to create additional instances.
I will think again

Did you find this page helpful?