160 likes | 175 Views
Fanciness of javascript functions. http://www.flickr.com/photos/pmarkham/3165964414/. Functions are objects. All functions are objects, and references to functions can be passed like C pointers var myfunc = function( a,b ) {return a+" "+b;}; var rv = myfunc ("happy", "birthday");
E N D
Fanciness ofjavascript functions http://www.flickr.com/photos/pmarkham/3165964414/
Functions are objects • All functions are objects, and references to functions can be passed like C pointers varmyfunc = function(a,b) {return a+" "+b;}; varrv = myfunc("happy", "birthday"); alert(rv);
References to functions are handy • For example, some JS APIs expect you to pass them a reference to a function. For example: <form>Name:<input id="nm" type="text"></form> <script> varfnCheck = function() { varnval= document.getElementById("nm").value; alert(nval== "" ? "Enter a name" : nval); setTimeout(fnCheck, 5000); } setTimeout(fnCheck, 5000); </script>
Very handy • Here's a great tool to use for seeing how variables point to functions http://www.pythontutor.com/javascript.html (It's also handy for debugging code that creates data structures.)
Passing a reference to a function <script> function showem(myarr, fn) { for (var x = 0; x < myarr.length; x++) fn(myarr[x]); } var f = (confirm("alert?")) ? function(e) {alert(e);} : function(e) {document.write(e);} vararr = [1,2,3,4]; showem(arr, f); </script>
Functions can be defined inside functions • When a function is called, it can define more functions inside of it function setupTimers() { for (var i = 1; i <= 3; i++) { var timer = function() {alert("wake up!");} setTimeout(timer, i*10000); } } setupTimers();
Functions can be members(aka “methods”) • You can assign a function to a slot in an associative array / object. • The function can reference the containing object via the “this” variable, as in Java. var obj = { ctr:0, incr:function() {return ++this.ctr;} }; for (var i = 0; i < 10; i++) document.write(obj.incr()+" ");
Functions can have members • Functions are objects, right? So they can have members if they are instantiated (with “new”) • This can be confusing to some programmers and is therefore often avoided (which is ok). varCounterObj = function() { this.ctr = 0; this.incr = function() {return ++this.ctr;}; }; varcobj = new CounterObj(); for (var i = 0; i < 10; i++) document.write(cobj.incr()+" ");
Function variables are subject to closure. • When a function is invoked, it canaccess any variable that was in scope when the function was defined. • If variable x is available when function is created, then variable x should be available at invocation. • This can be very good or very annoying.
Good closure: when you want to create private or temp variables • The “ctr” variable below is only visible to the incr function… effectively, it is a private variable. varCounterObj = function() { var ctr = 0; this.incr = function() {return ++ctr;}; }; var cobj = new CounterObj(); for (var i = 0; i < 10; i++) document.write(cobj.incr()+" ");
In case you need a refresher on local variables… • http://en.wikipedia.org/wiki/Local_variable • "In computer science, a local variable is a variable that is given local scope. Such a variable is accessible only from the function or block in which it is declared… contrasted with global variables."
A cleaner way to use private variables (no need for the “new” keyword) • Function defines private vars, then returns an object that contains functionality as members. varcounterObj = function() { var ctr = 0; return {incr: function() {return ++ctr;}} }; var cobj = counterObj(); for (var i = 0; i < 10; i++) document.write(cobj.incr()+" ");
You can also use nameless functions to avoid polluting the namespace. • For example, this version of the example avoids polluting the namespace with “counterObj”. (function() { varcounterObj = function() { var ctr = 0; return {incr: function() {return ++ctr;}} }; var cobj = counterObj(); for (var i = 0; i < 10; i++) document.write(cobj.incr()+" "); })();
Bad closure: when several functions access the same variable • All the “timer” functions access the same variable i • Closure means variables are not copied—they’re shared <script> function setupTimers() { for (var i = 1; i <= 3; i++) { var timer = function() {alert("wake up! "+i);} setTimeout(timer, i*1000); } } setupTimers(); </script>
Working around closure • Make a new variable for each function. • Each new variable is a local variable. function setupTimers() { for (var i = 1; i <= 3; i++) { var makeTimer = function(j) { var timer = function() {alert("wake up! "+j);} setTimeout(timer, j*1000); }; makeTimer(i); } } setupTimers();
What's next for you… • Work through the JS examples in this lecture. • If closures are confusing, search online for javascriptclosure examples • javascriptkit.com has some great examples • So does the course textbook “JavaScript: Good Parts” • (You ordered a copy when I told you to do so, right?) • Still confused? Ask instructor for help. • This lecture's material is indispensable. You must understand it if you are going to succeed with JS.