Created
January 20, 2015 14:18
-
-
Save gregtatum/d9436e31f977c462b6dd to your computer and use it in GitHub Desktop.
Storing state in functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Different ways to save state or configure a function | |
* | |
*/ | |
//------------------------------------------------- | |
// Typical prototypical inheritance | |
var Talker = function( phrase ) { | |
this.phrase = phrase; | |
}; | |
Talker.prototype = { | |
talk : function() { | |
console.log( this.phrase ); | |
} | |
}; | |
var sayThankYou = new Talker( "Why thank you so much." ); | |
sayThankYou.talk(); | |
// Mutation: | |
sayThankYou.phrase = "Gimme that!"; // easily mutable state | |
sayThankYou.talk(); | |
//------------------------------------------------- | |
// Binding a function | |
var say = function() { | |
console.log(this.phrase); | |
}; | |
var sayGoodbye = say.bind( {phrase: "That was fun, see you later!"} ); // | |
sayGoodbye(); | |
// Mutation: | |
var spanish = {phrase: "Adios amigo."}; | |
var sayAdios = sayGoodbyeSpanish = say.bind( spanish ); // | |
sayAdios(); | |
spanish.phrase = "Hasta luego." // the bound state object is mutable | |
sayAdios(); | |
//------------------------------------------------- | |
// Returning a function | |
var talk = function( phrase ) { | |
return function() { | |
// "phrase" is implicitely captured by this closure | |
// it maintains a persistent reference to the variable | |
console.log( phrase ); | |
} | |
} | |
var sayHello = talk( "Why hello there" ); | |
sayHello(); | |
// sayHello is immutable in this case and cannot be reconfigured | |
// Any new configuration will have to create a new function | |
var sayHi = talk( "Hi!" ); | |
sayHi(); | |
// Caveat: objects are passed by reference and are still mutable. | |
// So you could pass in an object and modify it by reference. |
That's a good point. I tend to create a default configuration object and extend it. You could combine that with a deep clone (which I didn't below.)
// Note: code requires lodash, and has not been tested
var talk = function( phraseObj ) {
var obj = _.extend({
phrase: "Greetings my friend"
}, phraseObj);
return function() {
console.log(obj.phrase);
}
};
var sayGreeting = talk();
sayGreeting();
// => Greetings my friend
var english = {phrase: "Hello there!"};
var sayHello = talk(english);
sayHello();
// => Hello there!
english.phrase = "Goodbye now.";
sayHello();
// => Hello there!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With a proper deep cloning function, such as lodash's
_.cloneDeep
, you can create immutable private objects, too.