{"id":179,"date":"2014-10-07T22:42:22","date_gmt":"2014-10-07T20:42:22","guid":{"rendered":"http:\/\/staratnight.de\/blog\/?p=179"},"modified":"2018-12-03T00:38:11","modified_gmt":"2018-12-02T22:38:11","slug":"sauberen-javascript-code-schreiben","status":"publish","type":"post","link":"https:\/\/staratnight.de\/blog\/sauberen-javascript-code-schreiben\/","title":{"rendered":"Sauberen JavaScript Code schreiben"},"content":{"rendered":"<p>Ich hatte letzte Woche auf die &#8222;Coole, leicht zu verstehende und sehr gut dokumentierte HTML5 und JavaScript Game Engine: Phaser.&#8220; hingewiesen.<\/p>\n<p>Mittlerweile habe ich mich ein wenig mit der Engine auseinandergesetzt, erste Tutorials gemacht und einige Erfahrungen damit gesammelt.<\/p>\n<p>Das Hauptproblem, welches ich von Anfang an hatte, war, dass der Code so unstrukturiert ist. Keine Klassen, alles in einer Datei, keine privaten Methoden, alles irgendwie chaotisch.<\/p>\n<p>Das muss besser gehen!, sagte ich mir und versuchte mich im Internet schlau zu machen. Ich habe auch sehr viele (sicherlich gute) Quellen gefunden, die mein Problem adressierten, aber verstanden habe ich es nicht und irgendwie f\u00fchlte es sich auch nicht gut an.<\/p>\n<p>Das Problem lag aber an mir. Ich hatte einfach zu wenig Erfahrung mit JavaScript. Ich habe die L\u00f6sungen nicht verstanden, weil JavaScript vom Grunde her gar nicht darauf ausgelegt ist, so genutzt zu werden, wie ich mir das vorgestellt habe.<\/p>\n<p>Zuf\u00e4llig bin ich dann \u00fcber ein Buch gestolpert, welches einen vielversprechenden Titel tr\u00e4gt: <a href=\"http:\/\/www.amazon.de\/JavaScript-objektorientiert-Verst%C3%A4ndlicher-effizienter-programmieren\/dp\/3864902029%3FSubscriptionId%3DAKIAIW663MLBQEBUNOEA%26tag%3Dstaratnightde-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D38649020\">&#8222;JavaScript objektorientiert&#8220; von Nicholas C. Zakas<\/a>.<\/p>\n<p>Nach der Lekt\u00fcre der etwa 115 Seiten kann ich von mir behaupten, ich habe JavaScript verstanden. Ich bin sicher weit davon entfernt, ein Profi zu sein, aber ich verstehe die Sprache, die Unterschiede zu objektorientierten Sprachen.\u00a0 Ich kann mittlerweile einige Konstrukte herstellen, die ich zun\u00e4chst vermisst habe. Ich habe erkannt das einige objektorientierte Ans\u00e4tze in JavaScript einfach keinen Sinn ergeben.<\/p>\n<p><!--more--><\/p>\n<p>Die wichtigsten Erkenntnisse schreibe ich hier noch einmal kurz zusammen. Das Buch sollte auf jeden Fall jeder lesen, der von Java, C#, C++ oder \u00e4hnlichen Sprachen kommt und mit JavaScript arbeiten m\u00f6chte.<\/p>\n<ul>\n<li><strong>Generell<\/strong><\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Es gibt keine Klassen, nur Objekte<\/li>\n<\/ul>\n<\/li>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Funktionen sollten &#8222;strict&#8220; verwendet werden um den Code gezwungener Ma\u00dfen sauberer zu halten (wer hat da gerade &#8222;Option Explicit&#8220; gesagt?)\n<pre style=\"padding-left: 30px;\" class=\"lang:js decode:true\">function foo(par1, par2) {\r\n    'use strict';\r\n    [....]\r\n}<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul style=\"padding-left: 30px;\">\n<li>Standardobjekte sollten nicht erweitert werden<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong>Primitive Typen und Referenztypen<\/strong>\n<ul>\n<li>funktionieren wie in den objektorientierten Sprachen auch<\/li>\n<li>Besonderheiten sind &#8222;null&#8220; und &#8222;undefined&#8220;<\/li>\n<li>Objekte sind dynamisch erweiterbar &#8211; immer [Ausnahme: <span style=\"font-family: courier new,courier;\">extensible<\/span>]<br \/>\n<span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">foo.bar = &#8222;newbar&#8220;<\/span><\/li>\n<li>Entfernen geht ebenfalls: <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">delete foo.bar;<\/span><\/li>\n<li>Objekten k\u00f6nnen Funktionen hinzugef\u00fcgt werden (Methoden)\n<pre class=\"lang:js decode:true\">var foo = { \r\n    bar: \"boo\",\r\n    far: function() { \r\n        console.log(\"go far\");\r\n    }\r\n};<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong>Funktionen<\/strong>\n<ul>\n<li>als Deklaration: <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">function foo(par1, par2) {<\/span><\/li>\n<li>als Ausdruck: <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">var bar = function foo(par1, par2) {<\/span><\/li>\n<li>Funktionen k\u00f6nnen als Werte verwendet werden<\/li>\n<li>Funktionen sind &#8222;object&#8220;<\/li>\n<li>Parameter sind benannt, k\u00f6nnen aber auch als array abgerufen werden (arguments[x])<\/li>\n<li>\u00dcberladung funktioniert nicht. Die letzte Methode gleichen Namens im Code gewinnt; nur durch interne Parameterpr\u00fcfung m\u00f6glich<\/li>\n<li>Methoden <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">call<\/span>, <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">apply<\/span> und <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">bind<\/span> auf Funktionen m\u00f6glich<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong>Objekte<\/strong>\n<ul>\n<li>Eigenschaftsattribute:\n<ul>\n<li><span style=\"font-family: courier new,courier;\">enumerable \u00a0<\/span> -&gt; Eigenschaften k\u00f6nnen aufgez\u00e4hlt werden<\/li>\n<li><span style=\"font-family: courier new,courier;\">configurable<\/span> -&gt; Objekt kann ge\u00e4ndert werden<\/li>\n<li><span style=\"font-family: courier new,courier;\">writeable\u00a0\u00a0\u00a0 <\/span>-&gt; Wert kann ge\u00e4ndert werden<\/li>\n<li><span style=\"font-family: courier new,courier;\">extensible\u00a0\u00a0 <\/span>-&gt; Objekt kann erweitert werden<\/li>\n<li><span style=\"font-family: courier new,courier;\">seal \u00a0 \u00a0 \u00a0 \u00a0 <\/span>-&gt; Objekt kann nicht erweitert und es k\u00f6nnen keine Eigenschaften entfernt werden<\/li>\n<li><span style=\"font-family: courier new,courier;\">freeze\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span>Objekt kann nicht erweitert und es k\u00f6nnen keine Eigenschaften entfernt werden, Werte k\u00f6nnen nicht ge\u00e4ndert werden<\/li>\n<\/ul>\n<\/li>\n<li>Zugriffseigenschaften\n<pre class=\"lang:js decode:true\">var foo = { \r\n    _bar: \"boo\",\r\n    get bar() {\r\n        return this._bar;\r\n    },\r\n    set(value) {\r\n        this._bar = value;\r\n    }\r\n};<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong>Konstruktoren und Prototypen<\/strong>\n<ul>\n<li>Konstruktoren sind Funktionen wie alle anderen<\/li>\n<li>Konstruktoren schreibt man per Konvention gro\u00df: <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">function Foo(par1, par2) {<\/span><\/li>\n<li>Instanzen werden mit <span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">new<\/span> erstellt<\/li>\n<li>Klassen\u00e4hnliche Konstrukte lassen sich \u00fcber Prototypen erstellen\n<pre class=\"lang:js decode:true\">function Foo(value) = { \r\n    this.bar = value;\r\n}\r\n\r\nFoo.prototype = {\r\n    constructor: Foo;\r\n    far: function() { \r\n        console.log(\"go far\" + this.bar);\r\n    }\r\n};\r\n\r\nvar one = new Foo(\"1\");\r\nvar two = new Foo(\"2\");\r\none.far(); \/\/ go far 1\r\ntwo.far(); \/\/ go far 2\r\n<\/pre>\n<\/li>\n<li>Es ist m\u00f6glich Prototypen ineinander zu schachteln um Vererbung zu erreichen<\/li>\n<li>Man kann Methoden (auch den Konstruktor) des Parents aufrufen (via\u00a0<span style=\"background-color: #ff6600; color: #333333; font-family: courier new,courier;\">Parent.call(this, &#8230;)<\/span>)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Dar\u00fcber hinaus gibt es noch einige weiterf\u00fchrende Konzepte:<\/p>\n<ul>\n<li><a href=\"http:\/\/molily.de\/js\/organisation-module.html\">Module Pattern<\/a><\/li>\n<li><a href=\"http:\/\/molily.de\/js\/organisation-instanzen.html\">Konstruktoren, Prototypen und Instanzen<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich hatte letzte Woche auf die &#8222;Coole, leicht zu verstehende und sehr gut dokumentierte HTML5 und JavaScript Game Engine: Phaser.&#8220; hingewiesen. Mittlerweile habe&hellip;<\/p>\n","protected":false},"author":2,"featured_media":493,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-179","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript"],"_links":{"self":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts\/179","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/comments?post=179"}],"version-history":[{"count":6,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts\/179\/revisions"}],"predecessor-version":[{"id":494,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/posts\/179\/revisions\/494"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/media\/493"}],"wp:attachment":[{"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/media?parent=179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/categories?post=179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/staratnight.de\/blog\/wp-json\/wp\/v2\/tags?post=179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}