FrontEndParty
Vanquishing Candyman
George Mauer
A story
Don't Say Candyman
//This is a forbidden function�//don't call it 5 times!�var sayCandyman = function() { � console.log("candyman");�}���//But then some teenagers did...�for(var i=0; i<5; i+=1)� sayCandyman();
But first let's talk functions
Two main ways to declare a function
function greet(whom, greeting) {� return "Hi " + whom + ", " + greeting;�}
=
var greet = function(whom, greeting) {� return "Hi " + whom + ", " + greeting;�}
You can return functions
function sayWelcome() {� var welcomeFn = function(whom) {� return “Welcome” + whom;� }
return welcomeFn;�}��var welcome = sayWelcome();�console.log( welcome("FrontEndParty") );
And now for some callback soup
Callback Soup - Getting into trouble
$('#females').click(function() {� list.empty();� people� .filter(function(p) { return p.gender == 'F' })� .forEach(function(p) { list.append('<li>'+p.name+'</li>') })� $('button').prop('disabled', false);� $(this).prop('disabled', true);� });� � $('#males').click(function() {� list.empty();� people� .filter(function(p) { return p.gender == 'M' })� .forEach(function(p) { list.append('<li>'+p.name+'</li>') })� $('button').prop('disabled', false);� $(this).prop('disabled', true);� });
Callback Soup - Cleansed
Cleaned up: http://jsbin.com/ozefer/3/edit
$('#females').click(function() {� showGender(this, 'F');� });� � $('#males').click(function() {� showGender(this, 'M');� });� � function showGender(thisButton, gender) { � list.empty();� people� .filter(function(p) { return p.gender == gender })� .forEach(function(p) { list.append('<li>'+p.name+'</li>') })� $('button').prop('disabled', false);� $(thisButton).prop('disabled', true);� }
Not bad, but we want beautiful code
Callback Soup - Scoured
$('#females').click(showGender('F'));� � $('#males').click(showGender('M'));�
� function showGender(gender) { return function() {� list.empty();� people� .filter(function(p) { return p.gender == gender })� .forEach(function(p) { list.append('<li>'+p.name+'</li>') })� $('button').prop('disabled', false);� $(this).prop('disabled', true);� } }
preventDefault is Annoying
$('#show-1').click(function(e) { � e.preventDefault();� $('.form-part').slideUp();� $('#form-part-1').slideDown() ;� });
preventDefault is Annoying
function preventDefault(fn){ return function(e) {� e && e.preventDefault && e.preventDefault();� fn.apply(this, arguments);� } };
But back to our story
Don't Say Candyman
//This is a forbidden function�//don't call it 5 times!�var sayCandyman = function() { � console.log("candyman");�}���//But then some teenagers did...�for(var i=0; i<5; i+=1)� sayCandyman();
Don't Say Candyman
function maxTimes(maxCount, fn) {� var lastResult, callCount = 0;� return function maxTimes() {� if(callCount >= maxCount)� return lastResult;� callCount +=1;� lastResult = fn.apply(this, arguments);� return lastResult;� }
Functions to the rescue: http://jsbin.com/ezigug/1/edit
Don't Say Candyman
function maxTimes(maxCount, fn) {� var lastResult, callCount = 0;� return function maxTimes() {� if(callCount >= maxCount)� return lastResult;� callCount +=1;� lastResult = fn.apply(this, arguments);� return lastResult;� }
Functions to the rescue: http://jsbin.com/ezigug/1/edit
Underscore Has Lots of These
Some real code
$(document).on('keydown',
runWhen(isPressedCtrl("P"), preventDefault(toPdf)) )�$(document).on('keydown',
runWhen(isPressedCtrl("F"), preventDefault(fullScreenSlide)) )�
Some real code
$(document).on('keydown',
runWhen(isPressedCtrl("P"), preventDefault(toPdf)) )�$(document).on('keydown',
runWhen(isPressedCtrl("F"), preventDefault(fullScreenSlide)) )�
//...�function isPressedCtrl(key){� var keyCode = key.charCodeAt(key);� return function isPressedCtrl(e){� return e && e.ctrlKey && e.which === keyCode; � }�}
function runWhen(filterFn, fn) { return function() {� if( filterFn.apply(this, arguments) )� fn.apply(this, arguments);�} }
Article by Raganwald
George Mauer
These Slides�http://tinyurl.com/funfuncs