Skip to content

Instantly share code, notes, and snippets.

@Kotauror
Last active March 6, 2018 20:56
Show Gist options
  • Save Kotauror/4446d72de2e641d0278fe548e850279a to your computer and use it in GitHub Desktop.
Save Kotauror/4446d72de2e641d0278fe548e850279a to your computer and use it in GitHub Desktop.
Playing with functions in JS

Playing with functions in JS

This note's purpose is to solidify knowledge on how to construct and use different types of functions in JS.

Constructors

Constructors are functions which allow to share behavior by their instances. They're basically like classes in Ruby.

var Party = function() {
  this.status = undefined
};

var Game = function() {};

Each new instance of Party will have a status. At the beginning it will be undefined.

console.log(party);
Party {status: undefined}

Each new instance of Game will be an empty object having no attributes.

Prototyping

Once we have constructors, we can create (prototype) methods that will be available to use by the instances of those constructors. Below I will describe 3 types of functions according to the argument passed.

No arguments passed

Game.prototype.playGame = function() {
  console.log("GAME HAS STARTED");
}

The function above accepts no arguments (hence empty ()). When called, it console logs a string.

var game = new Game();
game.playGame(); // console logs "GAME HAS STARTED"

No arguments passed, using other function inside

Game.prototype.howManyStars = function() {
  this.numberOfStars = countingStars();
}

var countingStars = function() {
  return Math.floor((Math.random() * 100) + 1);
}

In this example we create a howManyStars method to set the number of stars playing in the particular game. We pass no arguments, but inside of howManyStars methods we use the output of countingStars() function.

var game = new Game();
game.howManyStars(); // sets the numberOfStars to a random number from 0 to 100. 

Primitive argument passed

Game.prototype.duration = function(hours) {
  this.duration = hours;
}

In the example above, the duration function accepts one argument - hours. This argument is intended to be a primitive (string, number or symbol). What is important, at this point I don't want this argument to be another function.

When called, this method will set the duration of a particular instance of Game constructor.

var game = new Game();
game.duration(5);
console.log(game.duration) // 5

Callback as an argument

--> Preparation

JS (like for example Ruby) allows to pass functions as arguments in another functions.

We create two methods: beforeGame and afterGame available for the instances of Game.

Game.prototype.beforeGame = function(callback) {
 this.runBeforeGame = callback;
};

Game.prototype.afterGame = function(callback) {
 this.runAfterGame = callback;
};

In case of both methods, I would like to set the attributes (runBeforeGame and runAfterGame) to be functions. Those functions haven't been yet created.

--> Why is it useful?

Thanks to this operation, all instances of class game will have user-defined functions available to them. For example we have three games: basketball, pingpong and chess. Each of them has the runBeforeGame attribute which can be specific to its needs. In case of basketball: clean the floor, in case of pingpong: set up the table, in case of chess: reset the clock.

Each time I will want them to run a method, it will be available to them as an attribute. At the end, I want to be able to call:

  game.runBeforeGame();

and this way invoke a particular, predefined function.

--> Writing the callback

Once we have prototyped methods that are able to set the attribute to the function, it's time to write those functions.

var basketball = new Game();
basketball.beforeGame(function() {
  party = new Party();
  party.status = "started";
  console.log("Cleaning the floor");
  console.log("pumping the ball")
});

var pingpong = new Game();
pingpong.beforeGame(function() {
  party = new Party();
  party.status = "started";
  console.log("set up the table")
});


pingpong.afterGame(function() {
  party.status = "ended";
  console.log("The game is finished!")
});
  1. In both examples I call the methods on a particular instance of Game - basketball or pingpong.
  2. I call the empty prototyped methods drafter in the previous step (Preparation) and fill them with functions.
3) In case of `beforeGame`, I want to set the `runBeforeGame` attribute to a  function that:
  - creates a new instance of `Party`;
  - sets the `status` of this `party` to be `started`;
  - console logs a specific message.
4) In case of `afterGame`, I want to set the `runAfterGame` attribute to a function that:
  - changes the `status` of `party` to `ended`;
  - console logs `The game is finished`.
  1. In this stage we're still not calling those functions. We have just prepared them .

--> Using the callback

Now it's time to use the methods drafted in the previous two steps.

We create and run a new function called gaming that will run the whole sequence of relevant methods:

var gaming = function() {
  game.runBeforeGame();
  game.playGame();
  game.runAfterGame();
}

gaming();

Let's analyze it step by step:

  1. first, gaming function runs the game.runBeforeGame();

  2. runBeforeGame is an attribute of Game, which we set to a function when we called game.beforeGame

Game.prototype.beforeGame = function(callback) {
 this.runBeforeGame = callback;
};

var game = new Game();

game.beforeGame(function() {
  party = new Party();
  party.status = "started";
  console.log("New party was created!")
})
  1. this way by typing only game.runBeforeGame() we run all bunch of predefined things at once.

  2. second, gaming function runs the game.playGame() that simply console logs GAME HAS STARTED.

  3. third, gaming function runs the game.runAfterGame() that does all the things predefined when we called game.aftergame

Game.prototype.afterGame = function(callback) {
 this.runAfterGame = callback;
};

game.afterGame(function() {
  party.status = "ended";
  console.log("The game is finished!")
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment