Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.javascript > #4608

Re: (JavaScript) Wenn Variable X = Y dann Variable A = B

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups de.comp.lang.javascript
Subject Re: (JavaScript) Wenn Variable X = Y dann Variable A = B
Date 2015-06-28 23:11 +0200
Organization PointedEars Software (PES)
Message-ID <7762458.r6rIteaMLD@PointedEars.de> (permalink)
References <mmnb62.5n8.1@mid.maikkoenig.de> <Funktion-20150628013418@ram.dialup.fu-berlin.de> <mmo53e.3u0.1@mid.maikkoenig.de> <slrnmovbfp.42m.hjp-usenet3@hrunkner.hjp.at>

Show all headers | View raw


Peter J. Holzer wrote:

> On 2015-06-28 04:43, Maik Koenig <usenetspam@maikkoenig.de> wrote:
>> Am 28.06.2015 um 01:36 schrieb Stefan Ram:
>>>   Falls die Regel doch nicht affin-linear ist, könntest Du die
>>>   Zuordnung auch in einer globalen Tabelle speichern. Ich nehme
>>>   an, daß Du den globalen Namensraum in JavaScript nur möglichst
>>>   wenig verschmutzen willst und deswegen nur /einen/ globalen Namen
>>>   definierst, nämlich »koenig«. Ein Code-Fragment, das in eine
>>>   Funktion eingebaut werden könnte, wäre dann beispielsweis:
>>> 
>>> var myglobal = Function( "return this" )();
>>> myglobal.koenig = {}; // falls noch nicht existent
>>> var koenig = myglobal.koenig;
>>> koenig.Multiplikator = [];
>>> koenig.Multiplikator[ 20 ]= 1.6;
>>> koenig.Multiplikator[ 21 ]= 1.5;
>>> // console.log( koenig.Multiplikator[ 20 ]);
>>> // console.log( koenig.Multiplikator[ 21 ]);
>>> 
>>>   Danach könntest Du dann fast überall mit
>>> 
>>> Function( "return this" )().koenig.Multiplikator[ Ergebnis ]
> 
> Hmm. Namespace schonen ist gut und schön, aber da sieht der Laie vor
> lauter Boilerplate die Lösung nicht mehr.
> 
> (Abgesehen davon scheint mir »Function( "return this" )()« statt »var
> myglobal« den Teufel mit dem Beelzebub auszutreiben - es wird halt ein
> anderer Namespace "verschmutzt")

Nicht notwendigerweise ein anderer.  In diesem Fall wird sogar explizit in 
jedem Fall der globale Namespace auf höchst ineffiziente und fehlerträchtige 
Weise verschmutzt.  Dafür gibt es keinen logischen Grund, denn die Werte 
müssen nur innerhalb der Funktion bekannt sein.  Will man die 
Initialisierung bei jedem Aufruf vermeiden und somit die Effizienz 
optimieren, so sollte man stattdessen mit Closures bzw. dem Modul-Muster 
arbeiten; _nicht_ mit ständigen Referenzen auf das globale Objekt.  (Leider 
hat Stefan aus unserer Diskussion darüber in comp.lang.javascript [0] die 
falshcen Schlussfolgerungen gezogen.)

Ausserdem ist “Multiplikator” ein ungeeigneter Bezeichner, denn er 
suggeriert einen hier nicht vorhandenen Konstruktor.

Daher:

  var koenig = (function () {
    var o = {multiplikator: []};
    o.multiplikator[20] = 1.6;
    o.multiplikator[21] = 1.5;
    // console.log(koenig.multiplikator[20]);
    // console.log(koenig.multiplikator[21]);

    o.setY = function () {
      var x = document.getElementById("x").value;
      document.getElementById("y").value = koenig[x];
    }; 

    return o;
  }());

anschliessend:

  koenig.setY();

Jedoch siehe unten.

>> Was ich mir erhofft hatte: Ich baue eine Tabelle (imho vgl. Array in
>> JavaScript?) in der ich einfach durch Kommata getrennt alle Werte
>> eintrage.
> 
> Wenn Du Arrays schon kennst, warum verwendest Du sie dann nicht einfach?
> 
> Z.B. so:
> 
> <script>
>     a = [0, 3.17, 2.37, 2.02, 1.78, ]

Diese Schreibweise ist nicht kompatibel.  Verschiedene ECMAScript-
Implementierungen verhalten sich unterschiedlich, wenn bei einem Array-
Initialisierer das letzte Element nicht angegeben wird. [1a]  Diese 
Schreibweise am besten nicht verwenden; Tools wie Eclipse JSDT [1b] und 
JSHint [1c] können davor warnen.  (Anders verhält es sich bei Elementen am 
Anfang, d. h. führendem Komma, und bei Elementen dazwischen, d. h. Infix-
Komma.)

>     function f() {
>         var x = document.getElementById("x").value;
>         document.getElementById("y").value = a[x];
> ········
>     }
> </script>
> 
> <form>
>     <input id="x" name="x" onchange="javascript:f()"/>

Das name-Attribut erscheint hier unnötig, da das Formular nicht (cross-
browser) abgesendet werden kann (action-Attribut fe lt).

“javascript:” ist hier unnötig bzw. syntaktisch falsch.

Der “/” ist auch unnötig, aber nur dann syntaktisch falsch, wenn es sich 
nicht um XHTML oder HTML5 handelt (da hier das type-Attribut fehlt, ist es 
wahrscheinlicher gültiges HTML5 statt ungültiges XHTML).  Semantisch falsch 
ist er in HTML bis einschliesslich Version 4.01 und in XHTML, das als 
text/html ausgeliefert wird, weil dort “<input …/>” äquivalent zu
“<input …>&gt;” ist (eine manchmal eingebaute Fehlerkorrektur behandelt das 
*manchmal* anders). [2]

Statt in der Funktion erneut die Referenz zum Objekt, welches das das Event 
auslösende Element representiert, zu übermitteln, kann man diese auch 
einfach übergeben.  Dann kann sogar das id-Attribut weggelassen werden (wenn 
man den Wert sonst nicht braucht):

JS/ES:

  function setY (x)
  {
    x.form.elements["y"].value = a[x.value];
  }

HTML:

  <input onchange="setY(this)">

Dies kann dann analog zu oben auch stärker objektorientiert –

  var koenig = {
    factor: [0, 3.17, 2.37, 2.02, 1.78],

    setY: function (x) {
      x.form.elements["y"].value = this.factor[x.value];
    }
  };  

  …

  <input onchange="koenig.setY(this)">

– und zusätzlich mit dem Modul-Muster implementiert werden, so dass die 
Werte von aussen nicht direkt änderbar sind:

  var koenig = (function () {
    var factor = [0, 3.17, 2.37, 2.02, 1.78];

    return {
      setY: function (x) {
        x.form.elements["y"].value = factor[x.value];
      }
    };
  }());  

“factor” wird so quasi zu einer privaten Eigenschaft des Moduls und setY() 
zu seiner so genannten “privilegierten” Methode.

>     <input id="y" name="y"/>
> </form>

Ergänzend sollte erwähnt werden, dass MVVM (Model–View ViewModel), wie es 
zum Beispiel AngularJS [3] implementiert, genau für solche Fälle entwickelt 
wurde: Ein Steuerelement ändert seinen Wert, und ein anderes entsprechend 
dessen auch.  Denn der Wert des einen Steuerelements ändert sich über 
Bindungen an ein Datenmodell auch in diesem, und das andere Steuerelement 
ist an dasselbe Datenmodell gebunden.

Zukünftig (ECMAScript Edition 7) könnte dies mit Object.observe() auch ohne 
Events, Framework und Polling relativ einfach implementierbar sein. [4]

_______
[0] <news:JavaScript-20150528222318@ram.dialup.fu-berlin.de> pp.
[1a] Lahn, Thomas (2012). Features von ECMAScript-basierten
    Programmiersprachen. BSc CS SUPSI, FFHS. Kapitel 1.
    <http://PointedEars.de/es-matrix/application/doc/thesis.pdf#page=9>
    Siehe auch “ES Matrix” in der Signatur.
[1b] <https://www.eclipse.org/webtools/jsdt/>
[1c] <http://jshint.com/>
[2] <http://validator.w3.org/>
[3] <https://de.wikipedia.org/wiki/AngularJS>
    <https://angularjs.org/>
[4] 
<https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/observe>
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Back to de.comp.lang.javascript | Next | Find similar


Thread

Re: (JavaScript) Wenn Variable X = Y dann Variable A = B Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-06-28 23:11 +0200

csiph-web