{"id":806,"date":"2009-03-23T21:55:05","date_gmt":"2009-03-24T02:55:05","guid":{"rendered":"http:\/\/unitstep.net\/?p=806"},"modified":"2009-03-29T18:14:23","modified_gmt":"2009-03-29T23:14:23","slug":"javascript-functions-first-class-objects","status":"publish","type":"post","link":"https:\/\/unitstep.net\/blog\/2009\/03\/23\/javascript-functions-first-class-objects\/","title":{"rendered":"JavaScript functions: First-class objects"},"content":{"rendered":"
In JavaScript, functions are first-class objects<\/a>, meaning that they can be created, manipulated and passed around in the same manner as other objects\/variables in JavaScript. For example, a function can be created, stored in a variable or even be the return value of another function, as seen below:<\/p>\n In the rather stupid and contrived example above, we make a function We then call <\/p>\n Since functions are objects, and objects are passed and copied by reference<\/em><\/a>, the behaviour<\/a> should be fairly straightforward to those familiar with the concept. Here’s a quick example of what I’m talking about. Since JavaScript functions can be treated just like plain old objects, this means we can attach arbitrary properties to them – let’s see how that relates to making a “copy” of a function:<\/p>\n The key here is that the expression But let’s consider another example: What happens if we make a copy of a function and then redefine the original?<\/strong><\/p>\n The results are a bit strange – it appears that when we redefine Closer inspection yields the following answer: We were not actually redefining the function pointed to by This is illustrated by the following diagrams. In the first, the original function has been defined and two variables refer to it.<\/p>\n \n\n<\/p>\n In the second diagram, we have created a new function and altered the variable \n This point has relevance when talking about event handlers. Typically, when we bind functions to a specific events this involves copying a function reference over to some other variable or property. Whether we directly do this using traditional event registration<\/a> by using an expression like This means that after assigning the event handler, we cannot simply modify the original function to make changes to how the event handler works<\/strong>. This is because when we assign a new function the old one will still be referenced by the event handler. The proper way to do this at runtime would be simply to register the new function to the event and deregister the old one.<\/p>\n Another way to think of it is that you can often register anonymous functions to events; since they are anonymous you won’t have a reference to them after you assign them to the event handler so there is no way to modify them after the fact. This same logic applies equally when assigning non-anonymous functions to events.<\/p>","protected":false},"excerpt":{"rendered":" In JavaScript, functions are first-class objects, meaning that they can be created, manipulated and passed around in the same manner as other objects\/variables in JavaScript. For example, a function can be created, stored in a variable or even be the return value of another function, as seen below: function getPower(power) { return function(x) { return […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[328,4,137,277],"tags":[483,405,438],"_links":{"self":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/806"}],"collection":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/comments?post=806"}],"version-history":[{"count":7,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/806\/revisions"}],"predecessor-version":[{"id":814,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/806\/revisions\/814"}],"wp:attachment":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/media?parent=806"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/categories?post=806"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/tags?post=806"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}function getPower(power)\r\n{\r\n return function(x)\r\n {\r\n return Math.pow(x, power);\r\n }\r\n}\r\n\r\nvar x3 = getPower(3);\r\nwindow.alert(x3(3)); \/\/ Outputs 27.<\/code><\/pre>\n
getPower()<\/code> that returns another function which raises the given value to the exponent supplied by calling
getPower()<\/code>. (This is a bad way to do things for numerous reasons, but is just shown for the sake of providing a simple example)<\/p>\n
getPower<\/code> with a power of 3 and assign the returned function to the variable
x3<\/code>, and the output is as expected. Defining “inline” functions this way and manipulating them is closely associated with the concept of anonymous functions.<\/p>\n
Functions: Copied and passed by reference<\/h2>\n
function test() {window.alert(\"A Test\");}\r\nf = window.test;\r\nwindow.test.aProperty = 'Hello!';\r\nwindow.alert(f.aProperty); \/\/ Outputs \"Hello!\"\r\n\r\nf.aProperty = 'Goodbye!';\r\nwindow.alert(window.test.aProperty); \/\/ Outputs \"Goodbye!\"<\/code><\/pre>\n
f = window.test;<\/code> doesn’t make a complete copy of the function; instead it just ensures that the variable
f<\/code> will point at the same function object as
window.test<\/code>. So expressions that modify the underlying function object and its data will reflect in both
window.test<\/code> and<\/strong>
f<\/code>. Just think of those two variables as being different ways of accessing the same underlying data.<\/p>\n
function test() {window.alert(\"A Test\");}\r\n\r\nf = window.test;\r\nf(); \/\/ \"A Test\"\r\n\r\n\/\/ Redefine the original function.\r\ntest = function() {window.alert(\"A changed test\");};\r\n\r\nf(); \/\/ Still \"A Test\"!\r\nwindow.test(); \/\/ \"A changed test\"<\/code><\/pre>\n
test<\/code>, the changes are not reflected<\/strong> in the copy we created in variable
f<\/code>! Why is this?<\/p>\n
test<\/code><\/strong>. Instead, we created a new
Function<\/code><\/a> object in memory and then “pointed”
test<\/code> at this new function. The old function, formerly referenced by
test<\/code>, is still referenced by the variable
f<\/code> so that is why it continues to invoke that code.<\/p>\n
test<\/code> to refer to it; however the variable
f<\/code> still refers to the original function. Thus, the important thing to note is that when using the assignment operator for functions, they are copied by reference.<\/p>\n
\nThe original function is still referenced by f<\/code>\n<\/p>\n
Where this matters<\/h2>\n
element.onclick = someFunction<\/code> or whether it’s done using jQuery’s Event Helpers<\/a>, the effect is the same.<\/p>\n