0

so I'm having a problem with scope in javascript. I'm currently writing a little js app to allow me to create console-based(or looking) games on my website super quickly and have most of my utility and specific console-application functions stored within variables.

The problem occurs when I wanna add a "setTimeout" or Interval function and want to use my variable functions. I know about proxy but theres gotta be a better way than calling $.proxy every time I wanna refer to one of my functions, and calling proxy for everything im referring to WITHIN those functions.

jQuery(document).ready(function(){
  let gameStart = $.proxy(game.start, game);
  setTimeout(gameStart, 1000);
});

let options = {
  "consoleOutputDiv":"#console-output",
  "thisIsHowIFormatText":"something"
};

let utils = {
  formattxt: function(str){
    let formatted = str;
    let toReplace = options.thisIsHowIFormatText;
    //I need to refer to options.thisIsHowIFormatText now and thats not possible.
    //format text here!
    return formatted;
  }
}

let consolApp = {
  log: function(str){
    let stringToBeLogged = str;
    //ok so now I need to refer to formattxt which refers to options.thisIsHowIFormatText
    let format = $.proxy(utils.formattxt, utils, str);
    stringToBeLogged = format();
    //print stringToBeLogged to my console div.
  }
}

let game = {
  start: function() {
    let consol = $.proxy(consolApp.log, consolApp, 'please log me!');
    consol();
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='console-output'></div>

I just think there's gotta be a better way! That gets tedious and just looks gross to me constantly calling $.proxy everywhere to allow for my functions to work.

  • Possible duplicate: https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback/20279485 – Jared Smith Apr 15 '19 at 16:55
  • Why use `$.proxy` at all? Why not just call your functions and perhaps wrap your entire game entry point into a single function that's invoked when the DOM is ready? (i.e. `main()` or an IIFE that has access to your functions within that scope) – Charlie Schliesser Apr 15 '19 at 16:55
  • Replying to @Charlie Schliesser, problem im facing with that is I want the console app to be able to be referred to from other files because I plan to use the console itself as a shell for running multiple programs and games. – Nelson McCullough Apr 15 '19 at 16:58
  • @CharlieSchliesser just a guess, but I'd say because gamedev is so completely and thoroughly object-oriented that anyone working their way through a tutorial is going to have all of their logic in methods, and when you have to pass them as callbacks you lose context. Solutions to problems you create for yourself, yada yada. – Jared Smith Apr 15 '19 at 16:58
  • @NelsonMcCullough there are other (read: better) ways to do that, but that's a separate question. – Jared Smith Apr 15 '19 at 16:59
  • thats great! How should I phrase my google for that? lol – Nelson McCullough Apr 15 '19 at 17:00
  • @JaredSmith I thought this *was* the question being asked? – freedomn-m Apr 15 '19 at 17:02
  • @JaredSmith I'm about 2 months into self learning JavaScript for myself through the documentation/javascript.info only, so basically a tutorial yes – Nelson McCullough Apr 15 '19 at 17:02
  • @NelsonMcCullough https://medium.freecodecamp.org/javascript-modules-a-beginner-s-guide-783f7d7a5fcc – Jared Smith Apr 15 '19 at 17:02
  • @NelsonMcCullough Can you demonstrate the actual problem? "I need to refer to options.thisIsHowIFormatText now and thats not possible." You most certainly can use `options.thisIsHowIFormatText` at that point in your code. – Charlie Schliesser Apr 15 '19 at 17:03
  • @freedomn-m read literally, the question is how to avoid losing the object context when passing a method as a callback ($.proxy is AFAIK similar to Function.prototype.bind). – Jared Smith Apr 15 '19 at 17:03
  • 1
    @JaredSmith ah yes! Thank you a lot this makes a lot more sense. Time for restructuring I guess. – Nelson McCullough Apr 15 '19 at 17:04
  • @NelsonMcCullough you're welcome, and good luck. I'd stick with the revealing module pattern until you get to a point where you're ready for the standard toolchain, it'll get you pretty far. – Jared Smith Apr 15 '19 at 17:05

1 Answers1

0

Here's a small OOP suggestion for your code, perhaps just enough to give you an idea of how this kind of app might be structured:

  • When the window is loaded a new game is created, after a 1 second timeout.
  • The game creates a console when it is started.
  • The console uses a static utils method.

class Utils {
    static format(str){
       let formatted = str + "!!!"
       return formatted;
    }
}

class Console {
    log(str){
        let stringToBeLogged = Utils.format(str);
        console.log(stringToBeLogged)
    }
}

class Game {
    start() {
        let consol = new Console()
        consol.log('please log me...');
    }
}

window.addEventListener("load", () => {
  setTimeout(()=>{
     let g = new Game()
     g.start()
  }, 1000)
})
Kokodoko
  • 26,167
  • 33
  • 120
  • 197