Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
EightBall - intro to JS from an object-oriented perspective
// we're starting this function with an IIFE http://benalman.com/news/2010/11/immediately-invoked-function-expression/
// it's important to start this with a semicolon because otherwise any previously loaded JavaScript might try and invoke
// its last line using the anonymous function that we define here as its argument, and then invoke the resulting return value
// on line 63. That would be silly, yo. So we explicitly end the previous thought with a semicolon.
;(function () {
// we define an array of all of the possible predictions that our eight ball can make.
// unlike in Ruby, the use of all caps is purely conventional; JavaScript has no opinions about
// what capitalized variables mean.
var PREDICTIONS = [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes definitely',
'You may rely on it',
'As I see it, yes',
'Most likely',
'Outlook good',
'Yes',
'Signs point to yes',
'Reply hazy try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Focus and ask again',
'Don\'t count on it',
'My reply is no',
'My sources say no',
'Outlook not so good',
'Very doubtful'
];
// because we don't prefix EightBall with the var keyword, it is going to be a global variable;
// we are always careful to prefix locally-scoped variables with the var keyword except when we
// are certain we want to have the object available at higher scope. Since we intend to
// call EightBall(domElt) from outside of this file, we choose not to locally scope EightBall
EightBall = function (elt) {
this.view = new EightBall.View(elt);
this.model = new EightBall.Model();
this.setListeners();
};
EightBall.prototype = {
shake: function () {
this.model.predict();
this.view.renderPrediction(this.model.prediction);
},
setListeners: function () {
this.view.elt.addEventListener('click', this.shake.bind(this));
}
};
// this line is unnecessary but is nice for namespacing purposes:
// the predictions are now accessible as attributes in the EightBall
// class even though they were defined elsewhere
EightBall.predictions = PREDICTIONS;
EightBall.View = function (elt) {
this.elt = elt;
};
EightBall.View.prototype = {
renderPrediction: function (prediction) {
this.elt.innerHTML = prediction;
}
};
// this function appears to do nothing, but it actually
// allows us to construct EightBall.Model objects that
// inherit behavior from the EightBall.Model prototype
//as defined below
EightBall.Model = function () {};
EightBall.Model.prototype = {
predict: function () {
function generateRandomIndex () {
return Math.floor(Math.random() * EightBall.predictions.length)
}
this.prediction = EightBall.predictions[generateRandomIndex()]
}
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment