Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > de.comp.lang.javascript > #4608
| 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> |
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 …>>” 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
Re: (JavaScript) Wenn Variable X = Y dann Variable A = B Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-06-28 23:11 +0200
csiph-web