• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Frage zu JS Klassen

A

andreax

Guest
im folgenden Script verwende ich in einer Klasse da Schlüsselwort this
Erzeugt dieses Script Globale Variablen ausser setTacks ?
es wird kein Fehler geworfen und die console schweigt.
habe ich drotzdem etwas relewantes vergessen?
PHP:
////////////  javascript mit classes  ES6  ////////////////////
"use strict";

//CreateView Klasse zum erzeugen aller notwendigen HTML Elemente////
class CreateView{
	constructor(lines,targetobj)
	{
	this.aLines = lines;
	this.tob = targetobj;
	this.cbx = document.createElement('div');
	this.cbx.classList.add('gbar');
	this.codeLine = document.createElement('div');
	this.codeLine.classList.add('set-colors');
	this.checkB = document.createElement('div');
	this.checkB.classList.add('check-box');
	this.stick = document.createElement('span');
	this.stick.classList.add('sticker');
	this.nx = document.createElement('p');
	this.nx.innerHTML = "✓";
	this.nx.classList.add('next');
	}
get createC()
{
	console.log('creatC');

	for(var i = 0;i< this.aLines;i++)
	{
		console.log('ratatatata');
		var cl = this.codeLine.cloneNode(true);
		var cb = this.checkB.cloneNode(true);
		for(var j = 0;j< 5;j++)
		{
			cl.appendChild(this.stick.cloneNode(true));
			cb.appendChild(this.stick.cloneNode(true));
		}
		cb.appendChild(this.nx.cloneNode(true));
		this.cbx.appendChild(cl);
		this.cbx.appendChild(cb);
		this.tob.appendChild(this.cbx) ;
	}
}

get removC(){this.tob.innerHTML = "";}

}//
var setTacks = new CreateView(6,document.getElementById('play-box'));

setTacks.createC;
 
Danke für die Antwort.

Das kein Fehler geworfen wird sollte nur als hinweis dienen.

Mir ist wichtig das die Variablen die ich innerhalb der Klasse erzeuge nicht Global sind, also nur über die Klasse erreichbar sind.
 
Zuletzt bearbeitet von einem Moderator:
Du solltest eine Fehlermeldung bekommen, wenn du das new vergisst, da du im strict-Mode arbeitest.
 
Hallo
Die bind Funktion funktioniert soweit ganz gut.
nur kann ich nach der bindung der Listener-Funktion die Listener nicht mehr löschen.
daher habe ich nun die variable in eine eigene Klasse ausgelagert und auf bind verzichtet :(

Das ganze war für ein mastermind like Spiel das ich früher schon mal in Flash erstellt habe.
und nun zur Übungszwecken nach html5 js portiert habe bezw. auf ES6 updaten wollte.

es funktioniert wer das Spiel mal versuchen möchte kann es hier propieren . (geht auch auf dem Handy)

um die Farben auszuwählen einfach solange auf die schwarzen Buttons clicken bis die gewünschte Farbe Angezeigt wird.

Es wäre cool wenn jemand weis wie man die Listener Funktion wieder entbinden könnte um die Listener zu löschen.
habe schon auf MDN vergebens gesucht .

und bitte mit Kritik zum Es6 code nicht zurückhalten danke .
 
Code:
<!DOCTYPE html>

<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="description" content=""/>
		<meta name="keywords" content=""/>
		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
		<title>ES6 TEST</title>
		
		<style type="text/css">
	#test-b{
	width:100px;
	height:100px;
	border-radius:50%;
	background-color:#599;
	cursor:pointer;
	margin:auto;
	}
		</style>
	</head>
	<body>
	<div id="test-b" data-point="1"> </div>		
		
<script>
class ListenerTest
{
constructor()
{
this.ob = document.getElementById('test-b');
this.zahl = [1,2,3,4,5,6];
this.clicka = function(){console.log(this.zahl[4]);this.ob.removeEventListener('click',this.clicka,false);}.bind(this);

}
get setListener(){
this.ob.addEventListener('click',this.clicka,false);
console.log('setListenr',this.zahl[4]);//hier wird zahl gefunden weil this auf die Klasse zeigt.
}

}

var lisInst = new ListenerTest();
lisInst.setListener;
</script>
	</body>
</html>
 
Klassen-Konstruktoren lassen sich ohne new nicht aufrufen, unabhängig vom strict-Mode ("Class constructor [..] cannot be invoked without 'new'"). Solange du den globalen Namensraum also nicht explizit vollmüllst, passiert dahingehend gar nichts. Und noch ein Hinweis: da du ohnehin auf ES6 setzt, rate ich dir dazu, let statt var zu verwenden. Das Verhalten von let ist in den meisten Fällen intuitiver (siehe var-Hoisting). Auch kannst du Methoden ohne get festlegen (get removeC ist semantisch ziemlicher Unfug):

PHP:
class View{
  constructor(){
    // ..
  }

  render(){
    // ..
  }

  destroy(){
    // ..
  }
}

let view = new View();
view.render();
 
Danke für die Infos.
Ich halte schon ein paar Tage ausschau nach einem passenden Buch zu ES6 aber alle die ich bisher entdeckt habe
streifen das Thema nur mehr oder weniger .
mir gefällt das class und constructor konzept und auch dass man Methoden ohne function Schlüsselwort
verwenden kann und das set und das get . Ich hoffe das setzt sich bald durch und findet breite Browseruntersützung.
 
mir gefällt das class und constructor konzept
mir nicht, weil klassen nach oop klingen, "ein", nein "der" hauptpfeiler der oop ist aber kapselung, was mit klassen in js so nicht geht

und auch dass man Methoden ohne function Schlüsselwort verwenden kann
syntaktischer zucker

und das set und das get.
getter und setter finde ich grauenhaft, da sie kapselung verdecken würde(, wenn es sie denn geben würde)
gut finde ich async functions, auch generatoren, das konzept der arrow funktions, wobei die syntax dort mehr als grauenhaft ist
block scope wie in jeder anderen sprache, wobei js jetzt den vorteil bietet, beides zu unterstützen, darum finde ich die aussage falsch, man soll jetzt let statt var nutzen
promises, prinzipiell super, aber wenn man die promises-libs kennt die es schon wesentlich länger gibt sieht man, dass es auch besser geht
 
mir nicht, weil klassen nach oop klingen, "ein", nein "der" hauptpfeiler der oop ist aber kapselung, was mit klassen in js so nicht geht
Mag sein, aber das ist auch gar nicht Sinn & Zweck von JavaScript-Klassen. Letztlich sind sie nur syntactic sugar. Und wer große Anwendungen mit JavaScript baut (und noch nicht TypeScript verwendet) wird solche Entwicklungen mit offenen Armen empfangen. Da keywords wie private aber bereits reserviert sind (strict mode), gehe ich davon aus, dass in ferner Zukunft auch JavaScript private, protected & public unterstützen wird. The beast evolves.

getter und setter finde ich grauenhaft, da sie kapselung verdecken würde(, wenn es sie denn geben würde)
Nur weil es dafür keinen syntactic sugar gibt, heißt das nicht, dass es nicht möglich ist:

PHP:
'use strict';

function factory(firstname, lastname){
  var priv = {
    firstname: firstname,
    lastname: lastname
  };
  return{
    get fullname(){
      return [
        priv.firstname,
        priv.lastname
      ].join(' ');
    }
  };
}

let user = factory('john', 'doe');
console.log(user.fullname);
user.fullname = 'foo bar'; // TypeError: Cannot set property fullname of #<Object> which has only a getter (strict mode only)
user.firstname; // undefined (obviously)

(..) wobei die syntax dort mehr als grauenhaft ist
Was gibt es denn daran auszusetzen? Ich finde die Syntax absolut gelungen und bin froh, dass man in vielen Fällen Tastenanschläge spart:
PHP:
let users = rows.map(user => new UserModel(user));

block scope wie in jeder anderen sprache, wobei js jetzt den vorteil bietet, beides zu unterstützen, darum finde ich die aussage falsch, man soll jetzt let statt var nutzen
Vermutlich tut let in 99% der Fälle genau das, was ein Entwickler von var erwarten würde. So ziemlich jeder tritt doch mal in folgendes Fettnäpfchen:

PHP:
for(var i=0; i<10; i++){
	setTimeout(() => console.log(i), 0);
}
// output: 10, 10, 10, 10, 10, ..
..oder:
PHP:
var hello = 'world';
console.log(window.hello); // "world"

Da ist let einfach intuitiver und seit ES6 zu bevorzugen. Wenn man auf einen Anwendungsfall trifft, für den var tatsächlich die sinnvollere Lösung ist, warum nicht. Mir fällt spontan aber kein solcher Anwendungsfall ein, der nicht auf miesem Design beruht. Und wenn man var nutzt, gehören die Deklarationen meiner Meinung nach immer ganz oben im Gültigkeitsbereich platziert:

PHP:
function foo(){
  var a, b, c, d, e, f, g;
  // ..
  // code (..)
  // ..
}
 
Mir reicht das die Syntax entscheidend vereinfacht und übersichtlicher ist.
Das OO programmiern kenne ich noch von AS3 das war schon so strict wie Java
und war meiner Meinug nach für frontend entwickeln zu gut gemeint.
Weil man fürs web frontend gerne objecte (mc,classen) nachläd und man dann In AS3 über interfaces und
teilweise noch komplizierter zugreifen musst um an die Variablen der nachgeladenen Klassen zu gelangen.

zusammen fassend meine ich in ES6 it alles so einfach wie möglich möglch :)
 
Mag sein, aber das ist auch gar nicht Sinn & Zweck von JavaScript-Klassen. Letztlich sind sie nur syntactic sugar.
und das bemängel ich ja gerade, ich brauche keine neue syntax für etwas was ich (fast) schon mit anderer syntax schreiben kann (außer die alte syntax war schlecht verständlich).
ja, die class syntax ist übersichtlicher, aber nicht in dem maße, dass sich das gelohnt hätte. was aber tatsächlich fehlt, sind private member auf die mit prototype-methoden zugegriffen werden kann.

Da keywords wie private aber bereits reserviert sind (strict mode), gehe ich davon aus, dass in ferner Zukunft auch JavaScript private, protected & public unterstützen wird. The beast evolves.
die sind schon seit anbeginn reserviert (soll heißen, das sagt gar nichts), aber auch ich gehe davon aus, weil kein weg daran vorbeiführt

Nur weil es dafür keinen syntactic sugar gibt, heißt das nicht, dass es nicht möglich ist:

nein, daß meine ich nicht, ich will ja nicht zusätzlichen syntactic sugar, sondern dieser ist mir zuviel
ich rede genau von dem console.log(user.fullname);
der sinn von syntactic sugar soll ja nicht sein weniger zu tippen, sondern die übersicht zu erhöhen.
getter/setter tun das nicht, sie verdecken, daß es sich um eine get/set-funktion im hintergrund handelt.
als anwender von user.fullname hast du also immer die ungewissheit/das schlechte gefühl du greifst direkt auf eine membervariable zu

Was gibt es denn daran auszusetzen?
PHP:
let users = rows.map(user => new UserModel(user));
daß (jedenfalls meiner meinung nach)
PHP:
let users = rows.map(function(user)
{
  return new UserModel(user));
});
wesentlich verständlicher ist

Vermutlich tut let in 99% der Fälle genau das, was ein Entwickler von var erwarten würde.
ja, weil man es so kennt. ich bin nur gegen die REGEL verwende let statt var, sondern für das verständniss was macht var, was macht let, nimm das was passt, auch wenn das zu 99% let sein dürfte

Da ist let einfach intuitiver und seit ES6 zu bevorzugen.
ob es intuitiver ist, will ich nicht beurteilen, man kennt es aus (allen?) anderen sprachen eben so. und du kannst die lebensdauer von variablen kontrollieren, was mit var nicht geht.
von daher
* let wenn es kein var gibt: ok
* var wenn es kein let gibt: schlecht
* du hast die wahl: super

Wenn man auf einen Anwendungsfall trifft, für den var tatsächlich die sinnvollere Lösung ist, warum nicht. Mir fällt spontan aber kein solcher Anwendungsfall ein, der nicht auf miesem Design beruht.
Code:
let c = 1;
for (var k = 0; k < 10; ++k)
{
  if ((c *= 10) > 10000)
  {
    break;
  }
}
if (k < 10)
{
  console.log("schleife nicht bis zum ende gelaufen - mach was");
}


Und wenn man var nutzt, gehören die Deklarationen meiner Meinung nach immer ganz oben im Gültigkeitsbereich platziert:
das gilt (wenn dann) auch für let, weil es maximal die übersicht erhöt, sonst aber keinen zweck erfüllt
das problem ist doch eher, das 2 deklarationen überhaupt möglich sind.

- - - Aktualisiert - - -

getter/setter tun das nicht, sie verdecken, daß es sich um eine get/set-funktion im hintergrund handelt.
getter/setter wurden in hochsprachen als schnittstelle zu scriptsprachen eingeführt, weil man den "deppen die scriptsprachen programmieren" nicht zugetraut hat eine funktion aufzurufen
die einzige ausnahme, wo getter/setter nichts verdecken sind sprachen, in denen von hause aus NUR zugriff über getter/setter erfolgen kann
 
und das bemängel ich ja gerade, ich brauche keine neue syntax für etwas was ich (fast) schon mit anderer syntax schreiben kann (außer die alte syntax war schlecht verständlich).
PHP:
class Square extends Shape{ .. }

ja, die class syntax ist übersichtlicher, aber nicht in dem maße, dass sich das gelohnt hätte. was aber tatsächlich fehlt, sind private member auf die mit prototype-methoden zugegriffen werden kann.
PHP:
let Counter = (function(){
  let counter = Symbol('counter');
  
  function Counter(){
    this[counter] = 0;
  }
  
  Counter.prototype.inc = function inc(){
    return this[counter]++;
  };
  
  return Counter;
}());


let counter1 = new Counter;
console.log(counter1.inc()); // 0
console.log(counter1.inc()); // 1
console.log(counter1.inc()); // 2

let counter2 = new Counter;
console.log(counter2.inc()); // 0
console.log(counter2.inc()); // 1
console.log(counter2.inc()); // 2

die sind schon seit anbeginn reserviert (soll heißen, das sagt gar nichts), aber auch ich gehe davon aus, weil kein weg daran vorbeiführt
Die Hoffnung stirbt zuletzt :)

der sinn von syntactic sugar soll ja nicht sein weniger zu tippen, sondern die übersicht zu erhöhen.
getter/setter tun das nicht, sie verdecken, daß es sich um eine get/set-funktion im hintergrund handelt.
als anwender von user.fullname hast du also immer die ungewissheit/das schlechte gefühl du greifst direkt auf eine membervariable zu

daß (jedenfalls meiner meinung nach)
PHP:
let users = rows.map(function(user)
{
  return new UserModel(user));
});
wesentlich verständlicher ist
Subjektiv.

ja, weil man es so kennt. ich bin nur gegen die REGEL verwende let statt var, sondern für das verständniss was macht var, was macht let, nimm das was passt, auch wenn das zu 99% let sein dürfte
Deshalb habe ich zum Artikel über Hoisting verlinkt. Ich finde es jedenfalls sinnvoller, wenn ein JavaScript-Einsteiger blind let verwendet, statt var, eben weil man das Verahlten von anderen Sprachen so kennt und erwartet. Dass man versteht was man da tut, sollte langfristig aber immer das Ziel sein.

Code:
let c = 1;
for (var k = 0; k < 10; ++k)
{
  if ((c *= 10) > 10000)
  {
    break;
  }
}
if (k < 10)
{
  console.log("schleife nicht bis zum ende gelaufen - mach was");
}
Würde man hier ein let (oder ein var ganz oben) verwenden, wäre der Gültigkeitsbereich von k direkt klar ablesbar. Meiner Meinung nach ist das ein mieser Style.

das gilt (wenn dann) auch für let, weil es maximal die übersicht erhöt, sonst aber keinen zweck erfüllt
das problem ist doch eher, das 2 deklarationen überhaupt möglich sind.
Ich finde es für die Übersicht absolut wichtig, dass man direkt erkennt, in welchem Bereich eine Variable gültig ist, denn daraus ergibt sich, in welchen Teilen einer Funktion eine Variable überhaupt benutzt wird / werden kann. Gerade bei komplexen Funktionen kommt dieser Vorteil zum Tragen.
 
PHP:
class Square extends Shape{ .. }
???

PHP:
let counter = Symbol('counter');
ok, mit Symbol bekommst du das jetzt auch hingetrickst, aber warum nicht vernümpftig?

Deshalb habe ich zum Artikel über Hoisting verlinkt.
hoisting ist ja erst mal unabhängig vom scope (zwar für alle variablen (vor es6) und damit auch für alle mit var deklarierten verbunden) und auch nichts schlechtes

Ich finde es jedenfalls sinnvoller, wenn ein JavaScript-Einsteiger blind let verwendet, statt var, eben weil man das Verahlten von anderen Sprachen so kennt und erwartet.
nein, dann kommst du da hin, was crockford verbrochen hat. er wollte ein verständniss für js entwickeln, hat blöderweise regeln aufgestellt.
jeder dep verwendet heute diese regeln und das verständniss ist bei kaum einen eingetreten der das nicht schon vorher hatte. bei vielen die neu anfangen und stur nach diesen regen arbeiten aber sonst vielleicht den hintergrund verstanden hätten, weil sie über den einen oder anderen fehler gestolpert wären, wird dieses verständniss nie eintreten.
deswegen sollte js anfängern meiner meinung als erstes var und erst viel später let gezeigt bekommen

Dass man versteht was man da tut, sollte langfristig aber immer das Ziel sein.
"sollte" sagt alles

Würde man hier ein let (oder ein var ganz oben) verwenden, wäre der Gültigkeitsbereich von k direkt klar ablesbar.
der gültigkeitsbereich von k ist klar definiert und damit direkt ablesbar

Ich finde es für die Übersicht absolut wichtig, dass man direkt erkennt, in welchem Bereich eine Variable gültig ist, denn daraus ergibt sich, in welchen Teilen einer Funktion eine Variable überhaupt benutzt wird / werden kann.
die übersicht hast du aber auch mit var, diese sind eben in der gesammten funktion gültig, sobald du var siehst, weisst du das
erst wenn closures ins spiel kommen wird es unübersichtlich

Gerade bei komplexen Funktionen kommt dieser Vorteil zum Tragen.
manch einer würde wieder behaupten funktionen mit mehr als 10 zeilen darf es nicht geben, aber da bin ich realischisch
 
Vererbung ist mit dem neuen class-Konstrukt deutlich einfacher umzusetzen. Es ist also nicht "nur" syntactic sugar.

ok, mit Symbol bekommst du das jetzt auch hingetrickst, aber warum nicht vernümpftig?
Mir ging es nur darum aufzuzeigen, dass das mit JavaScript durchaus machbar ist. Das geht auch ohne Symbol (dafür etwas umständlicher).

hoisting (..) und auch nichts schlechtes
Ich sagte nicht dass es schlecht ist. Es ist nicht intuitiv und das Verhalten ist für Leute die von C++, C#, Java, whatever kommen einfach unerwartet.

nein, dann kommst du da hin, was crockford verbrochen hat. er wollte ein verständniss für js entwickeln, hat blöderweise regeln aufgestellt.
jeder dep verwendet heute diese regeln und das verständniss ist bei kaum einen eingetreten der das nicht schon vorher hatte. bei vielen die neu anfangen und stur nach diesen regen arbeiten aber sonst vielleicht den hintergrund verstanden hätten, weil sie über den einen oder anderen fehler gestolpert wären, wird dieses verständniss nie eintreten.
deswegen sollte js anfängern meiner meinung als erstes var und erst viel später let gezeigt bekommen
Ob sich jemand tatsächlich intensiv mit der Materie befasst kann ich nicht beeinflussen. Und da ändert es dann auch nichts, wenn ich denjenigen erstmal in die üblichen var-Fettnäpfchen treten lasse.

der gültigkeitsbereich von k ist klar definiert und damit direkt ablesbar
Der Gültigkeitsbereich von k erstreckt sich über die gesamte Funktion. Deklariert wurde k aber innerhalb der for-Anweisung.

Mies:
PHP:
for(var k=0; k<10; k++){}
console.log(k); // = 10

Besser:
PHP:
var k;
// ..
for(k=0; k<10; k++){}
// ..

Ideal:
PHP:
for(let k=0; k<10; k++){}
console.log(k); // k is not defined

Im 2. und 3. Beispiel sind die Variablen dort deklariert worden, wo ihr Gültigkeitsbereich tatsächlich beginnt. Wer bspw. aus der C, C++, C#, Java, Scala Ecke kommt, wird sich mit dem 3. Beispiel am wohlsten fühlen. Ein sinnvolles Argument eine var-Deklaration irgendwo in den Tiefen einer Funktion zu platzieren, gibt es nicht.

Nun denn, ich bin dann mal raus :)
 
Ob sich jemand tatsächlich intensiv mit der Materie befasst kann ich nicht beeinflussen. Und da ändert es dann auch nichts, wenn ich denjenigen erstmal in die üblichen var-Fettnäpfchen treten lasse.
doch, weil er dann gezwungen ist sich damit zu befassen, dass nur derjenige sich dann auch damit befassen wird, welcher das auch will, daß kannst du nicht beeinflussen.


Der Gültigkeitsbereich von k erstreckt sich über die gesamte Funktion. Deklariert wurde k aber innerhalb der for-Anweisung.
ja, so ist das definiert

warum? der gültigkeitsbereich von k ist ersichtlich

nein, weder besser noch schlechter
wenn du die variable mit let deklariert hättest, könnte ich das argument eines evtl. später dazukommenden äußeren blockes noch nachvollziehen, so ergibt sich aber keine verbesserung.

wo ist das ideal, wenn es so nicht geht

C, C++, C#, Java, Scala Ecke kommt, wird sich mit dem 3. Beispiel am wohlsten fühlen.
ich komme aus der c++ ecke und wüsste nicht, was es an einer optionalen deklarationsart für funktionsglobale variablen schlecht sein sollte - solange es optional bleibt

Ein sinnvolles Argument eine var-Deklaration irgendwo in den Tiefen einer Funktion zu platzieren, gibt es nicht.
den gibt es aber auch nicht für let, wo ist da der unterschied? ob alle variablen am scopeanfang ala ansi c oder an jeder beliebigen stelle wie in c99 deklariert werden (dürfen) ist geschmackssache
 
Zurück
Oben