{"id":497,"date":"2011-02-19T00:21:40","date_gmt":"2011-02-18T23:21:40","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=497"},"modified":"2011-02-19T12:28:53","modified_gmt":"2011-02-19T11:28:53","slug":"javascript-selbstausfuehrende-anonyme-funktionen","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/javascript-selbstausfuehrende-anonyme-funktionen\/","title":{"rendered":"Javascript: selbstausf\u00fchrende, anonyme Funktionen"},"content":{"rendered":"<p>Ziel des Artikels: Den Sinn folgenden Konstrukts verstehen<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\n(function(window, document, undefined) {\r\n    \/\/some fancy code\r\n})(this, document);\r\n<\/pre>\n<p>Mag auf den ersten Blick f\u00fcr den nicht t\u00e4glich mit Javascript schaffenden Menschen be\u00e4ngistend aussehen. Aber der Reihe nach. Eine \u00e4hnliche Konstruktion kommt \u00fcbrigens in jQuery zum Tragen (<a href=\"http:\/\/code.jquery.com\/jquery-1.5.js\">siehe source<\/a>). <\/p>\n<h2>Anonym?<\/h2>\n<p>Erstmal ist die Funktion anonym, also ohne Namen. Einfach aus dem Grund, weil sie keinen Namen braucht, da sie sich ja selbst aufruft. Man k\u00f6nnte ihr \u00fcbrigens einen Namen geben, funktionieren w\u00fcrde es trotzdem. Vereinfacht sieht das dann z.B. so aus:<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\n(function nichtMehrAnonym() {\r\n    \/\/some fancy code\r\n})();\r\n<\/pre>\n<p>Vorteil: Wenn wir vorhaben, die Funktion aus sich selbst heraus nochmal aufzurufen, ist das so bequemer m\u00f6glich (Rekursion).<\/p>\n<h2>Warum die Parameter?<\/h2>\n<p><i>window<\/i> hat innerhalb der Funktion den Wert, den <i>this<\/i> au\u00dferhalb der Funktion hat. Da sich die Funktion im globalen Scope befindet, ist <i>window<\/i> dasselbe wie <i>this<\/i>. Leicht festzustellen hierdurch:<\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;script&gt;\r\nalert(this === window); \/\/true\r\n&lt;\/script&gt;\r\n<\/pre>\n<p>Man kann nat\u00fcrlich auch <i>window<\/i> anstelle von <i>this<\/i> schreiben. Selbiges geschieht mit <i>document<\/i>, f\u00fcr das man auch <i>this.document<\/i> schreiben k\u00f6nnte, da das <i>document<\/i> ein Kind des <i>window<\/i> ist.<\/p>\n<p>\n<b>Stellen sich drei Fragen zu den Parametern: <\/b><\/p>\n<ol>\n<li>Warum sollte man sowas tun?<\/li>\n<li>Darf man das?<\/li>\n<li>Was ist mit undefined?<\/li>\n<\/ol>\n<p><b>Antwort zu 1)<\/b>: Hat zwei Gr\u00fcnde. Der erste ist Performance. Man spart sich einen Schritt nach oben im Variablenscope, weil wir nun innerhalb unserer Funktion quasi lokal <i>window<\/i> und <i>document<\/i> rumfliegen haben. Javascript schaut n\u00e4mlich zuerst die lokalen Variablen und dann erst die globalen an, also einen Schritt gespart &#8211; auch wenn der Gewinn minimal ist. Der zweite Grund ist: Minification und dadurch Codegr\u00f6\u00dfe. Jage ich den Code durch einen Javascript-Minifier wird daraus z.B.<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\n(function(w, d, u) {\r\n    \/\/some fancy code\r\n})(this, document);\r\n<\/pre>\n<p>Wenn ich nun innerhalb meiner Funktion vorher <i>document.getElementById(&#8230;)<\/i> hatte, habe ich nun d.getElementById(&#8230;). Sch\u00f6n zu sehen im <a href=\"http:\/\/code.jquery.com\/jquery-1.5.min.js\">Source von jQuery in der minified-Variante<\/a>.<\/p>\n<\/p>\n<p><b>Antwort zu 2 und 3)<\/b>: Ja, man darf! <\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;script&gt;\r\nalert(typeof undefined); \/\/undefined\r\nundefined = &quot;evil&quot;;\r\nalert(typeof undefined); \/\/string\r\n&lt;\/script&gt;\r\n<\/pre>\n<p>Noch Fragen? Mal eiskalt <i>undefined<\/i> \u00fcberschrieben. Und genau das ist auch der Grund, warum <i>undefined<\/i> erwartet, aber beim Aufruf nicht \u00fcbergeben wird. Angenommen ich habe folgendes:<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\n(function() {\r\n    if (x === undefined) {\r\n        \/\/...\r\n    }\r\n})();\r\n<\/pre>\n<p>Jetzt geht jemand daher, und belegt im globalen Scope fr\u00f6hlich <i>undefined<\/i> mit <i>true<\/i>. W\u00fcrde einiges an Verwirrung in meiner Funktion stiften. Deswegen gehen wir auf Nummer sicher und bewahren uns ein &#8222;wahres&#8220; <i>undefined<\/i> in unserer Funktion durch einen nicht \u00fcbergebenen Parameter, der auch dann erhalten bleibt wenn jemand au\u00dferhalb Schabernack treibt. Gut, haben wir das mit den Parametern also gekl\u00e4rt.<\/p>\n<h2>Und wozu das Ganze?<\/h2>\n<p>Erstmal wie angesprochen ein Qu\u00e4ntchen Performance durch einen eingesparten Schritt im Scope. Aber das gr\u00f6\u00dfere Argument ist: Der globale Variablenraum wird nicht mit unn\u00f6tig vielen Variablen verschmutzt. Da alles in einer Funktion gekapselt ist, sind die Variablen lokal, die sonst global w\u00e4ren. So sind z.B. Libraries gut vor \u00dcberschneidungen von internen Variablennamen mit dem Code des Nutzers bewahrt. Und letztlich: <b>Der &#8222;Booah, cool&#8220;-Effekt<\/b>.<\/p>\n<h2>Geht da noch was?<\/h2>\n<p>Aber ja! Die self-executing-function darf auch flei\u00dfig returnen. Beispiel?<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\nvar myvar = (function() {\r\n\treturn &quot;somestuff&quot;;\r\n})();\r\n\r\nalert(myvar === &quot;somestuff&quot;); \/\/true\r\n<\/pre>\n<p>Credits an <a href=\"http:\/\/paulirish.com\/\">Paul Irish<\/a> f\u00fcr die sehr nett gemachten Screencasts \u00fcber Tricks im jQuery-Source, zu sehen <a href=\"http:\/\/net.tutsplus.com\/articles\/lectures\/11-more-things-i-learned-from-the-jquery-source\/\">hier<\/a> und <a href=\"http:\/\/net.tutsplus.com\/tutorials\/javascript-ajax\/10-things-i-learned-from-the-jquery-source\/\">hier<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ziel des Artikels: Den Sinn folgenden Konstrukts verstehen (function(window, document, undefined) { \/\/some fancy code })(this, document); Mag auf den ersten Blick f\u00fcr den nicht t\u00e4glich mit Javascript schaffenden Menschen be\u00e4ngistend aussehen. Aber der Reihe nach. Eine \u00e4hnliche Konstruktion kommt &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/javascript-selbstausfuehrende-anonyme-funktionen\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,3],"tags":[],"class_list":["post-497","post","type-post","status-publish","format-standard","hentry","category-javascript","category-webdev"],"_links":{"self":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/497","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/comments?post=497"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/497\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}