jobo: jslint und Crockfords memoizer-Funktion

Hallo,

wenn ich Crockfords memoizer-Funktion

  
var memoizer = function (memo, formula) {  
	var recur = function (n) {  
		var result = memo[n];  
		if (typeof result !== 'number') {  
			result = formula(recur, n);  
			memo[n] = result;  
		}  
		return result;  
	};  
	return recur;  
};  
var factorial = memoizer([1, 1], function (recur, n) {  
	return (n * recur(n - 1));  
});  
var fibonacci = memoizer([0, 1], function (recur, n) {  
	return (recur(n - 1) + recur(n - 2));  
});  

(s.a. http://books.google.de/books?id=mOQDYOM8TiYC&pg=PT62&lpg=PT62&dq=function+memoizer+crockford&source=bl&ots=ErqT963EcW&sig=JGV3vJyFj5XyV9h8ShNh8gekU-Q&hl=de&ei=ufTLTYnTI8Pn0QGf25TLBg&sa=X&oi=book_result&ct=result&resnum=2&ved=0CCUQ6AEwAQ#v=onepage&q&f=false bzw. http://www.livestream.com/etsy/video?clipId=pla_1463e546-47ed-4a93-b59a-bd52b236e8b8 bei ca. 45.50) in http://jslint.com/ eingebe, erhalte ich einen Fehler:

"Error:

Problem at line 5 character 30: 'recur' has not been fully defined yet.

result = formula(recur, n);"

Warum?

Gruß

jobo

  1. Hallo,

    "Error:

    Problem at line 5 character 30: 'recur' has not been fully defined yet.

    result = formula(recur, n);"

    Warum?

    Weil die Definition der Funktion recur erst in Zeile 11 abgeschlossen wird.

    Diesen "Fehler" kannst du getrost ignorieren. Er lässt sich bei einer rekursiven Funktion kaum vermeiden.
    Zwar ginge das mit arguments.calleee, was auch auf die FUnktion selber verweist, aber das verursacht unnötigen Overhead und beeinträchtigt die Performance.

    Gruß, Don P

    1. Hallo,

      Zwar ginge das mit arguments.calleee [...]

      arguments.callee natürlich.

      Gruß, Don P

    2. Hallo,

      "Error:

      Problem at line 5 character 30: 'recur' has not been fully defined yet.

      result = formula(recur, n);"

      Warum?

      Weil die Definition der Funktion recur erst in Zeile 11 abgeschlossen wird.

      Diesen "Fehler" kannst du getrost ignorieren. Er lässt sich bei einer rekursiven Funktion kaum vermeiden.
      Zwar ginge das mit arguments.calleee, was auch auf die FUnktion selber verweist, aber das verursacht unnötigen Overhead und beeinträchtigt die Performance.

      var recur;
      recur = ...

      beruhigt jslint.

      1. Hallo,

        var recur;
        recur = ...

        beruhigt jslint.

        Dann ist recur aber eine lokale Variable innerhalb der Funktion "recur" und verweist nicht auf sich selbst ("recur").

        Abgesehen davon ist der Code from Mr. JSLint persönlich.

        Gruß

        jobo

        1. Hallo,

          Hallo,

          var recur;
          recur = ...

          beruhigt jslint.

          Dann ist recur aber eine lokale Variable innerhalb der Funktion "recur" und verweist nicht auf sich selbst ("recur").

          Abgesehen davon ist der Code from Mr. JSLint persönlich.

          Der hier aber das selbe zu sagen scheint: http://tech.groups.yahoo.com/group/jslint_com/message/2022

          "Declare the variable before giving it a value that depends on the
          same variable".

          Als Antwort auf die Feststellung, dass der Fehler inkonsitent wäre.

          Gruß

          jobo

          1. Hallo,

            "Declare the variable before giving it a value that depends on the
            same variable".

            Als Antwort auf die Feststellung, dass der Fehler inkonsitent wäre.

            Die genaue Erklärung zum Warum der Fehlermeldung liefert er dort auch:

            --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@> wrote:

            There are some cases where it is troublesome to use a variable while it is

            being initialized, such as

            var x = x + 1;

            JSLint is not able to determine which cases are troublesome and which are

            useful, so it warns on all cases.

            Der letzte Satz erklärt wohl alles.

            Gruß, Don P

            1. Hallo,

              Der letzte Satz erklärt wohl alles.

              Erklärt aber nicht, warum das inkonistent ist, oder?

              [script lang=javascript]
              var testFn = function () {
                  var dom = (function () {
                      var ready = function (e) {
                          //do something
                      };
                      return {
                          contentLoaded: function (e) {
                              if (dom.isReady) {
                                  return;
                              }
                              dom.isReady = true;
                              ready(e);
                          },
                          isReady: false
                      };
                  }());
              };
              // 2 Fehler
              var dom = (function () {
                  var ready = function (e) {
                      //do something
                  };
                  return {
                      contentLoaded: function (e) {
                          if (dom.isReady) {
                              return;
                          }
                          dom.isReady = true;
                          ready(e);
                      },
                      isReady: false
                  };
              }());
              // Fehlerfrei
              [/code]

              aus http://tech.groups.yahoo.com/group/jslint_com/message/2021

              Gruß

              jobo

              1. Hallo,

                Der letzte Satz erklärt wohl alles.

                Erklärt aber nicht, warum das inkonistent ist, oder?

                Nein, das nicht. Ich halte es für einen Bug in JSLint.
                Aber was soll's... JSLint hätte ich niemals selber programmieren können, daher schmälert diese kleine Inkonsistenz in keiner Weise meine Hochachtung vor Crockfords Leistung.

                Auf seinen Vortrag "JavaScript - The Good Parts" bin ich zum Glück ziemlich früh (am Anfang meiner ersten ernsthaften Versuche mit der Sprache vor einigen Jahren) gestoßen, was mich gleich enorm vorangebracht und vor vielen Fehlern bewahrt hat, die man sonst als reiner Autodidakt unweigerlich begangen hätte.

                Gruß, Don P

                1. Hallo,

                  Nein, das nicht. Ich halte es für einen Bug in JSLint.
                  Aber was soll's... JSLint hätte ich niemals selber programmieren können, daher schmälert diese kleine Inkonsistenz in keiner Weise meine Hochachtung vor Crockfords Leistung.

                  Die regulären Ausdrücke fand ich jetzt erstmal überraschend komplex, und "use strict" war mir unbekannt bis dahin. Ansonsten dachte ich vielleicht mal eine gute Übung, sich sukkzessive durch den JSLint-Code zu wurschteln.

                  Auf seinen Vortrag "JavaScript - The Good Parts" bin ich zum Glück ziemlich früh (am Anfang meiner ersten ernsthaften Versuche mit der Sprache vor einigen Jahren) gestoßen, was mich gleich enorm vorangebracht und vor vielen Fehlern bewahrt hat, die man sonst als reiner Autodidakt unweigerlich begangen hätte.

                  Ja, es hilft aber auch beim Sortieren der eigenen Fehler, wenn man sich den Vortrag erst etwas später anschaut (;-). Der neueste Vortrag, der mir via Twitter jetzt unterkam https://forum.selfhtml.org/?t=204924&m=1388501 barg für mich auch wieder erhellendes. U.a. zB. diese "Function-make-Functions"-Geschichte.

                  Gruß

                  jobo

            2. --- In jslint_com@yahoogroups.com, "Douglas Crockford" <douglas@> wrote:

              There are some cases where it is troublesome to use a variable while it is
              being initialized, such as

              var x = x + 1;

              Der Fall ist ziemlich konstruiert, wieso sollte man auf diese Idee kommen und was sollte man als Ergebnis erwarten?

              Man kann schon in der Deklaration auf den Variablenwert zugreifen, er ist dann undefined. Es kommt natürlich NaN heraus, wenn man undefined + 1 rechnet. Okay, das ist Quatsch. Aber dieses Pattern ist eigentlich in Ordnung:

              var foo = foo || [1,2,3];

              Wenn schon eine Variable foo existiert, dann nimmt er diese, sofern der Wert truthy ist. Dann wird die Redeklaration ignoriert.

              Andernfalls legt er eine Variable an. Dann hat wegen dem Hoisting von Variable Declarations die Variable auf jeden Fall den Wert undefined, also nimmt er [1,2,3].

              Das Pattern ist zwar nicht so häufig, aber »troublesome« ist es nun nicht per se.

              Mathias

              1. Hallo,

                Man kann schon in der Deklaration auf den Variablenwert zugreifen, er ist dann undefined. Es kommt natürlich NaN heraus, wenn man undefined + 1 rechnet. Okay, das ist Quatsch. Aber dieses Pattern ist eigentlich in Ordnung:

                var foo = foo || [1,2,3];

                  
                var foo = foo || [1, 2, 3];  
                
                

                fehlerfrei in JSLint: "Global foo"

                Gruß

                jobo

                1. var foo = foo || [1, 2, 3];

                  
                  >   
                  > fehlerfrei in JSLint: "Global foo"  
                    
                  Hingegen:  
                    
                  (function () {  
                  var foo = foo || [1, 2, 3];  
                  alert(foo);  
                  }());  
                    
                  Error:  
                  Problem at line 2 character 11: Unexpected 'foo'.  
                    
                  Gut, das Pattern ist auch vor allem global sinnvoll, denn nur da kann es dazu kommen, dass Scriptreihenfolge unterschiedlich ist. Der Async-Code von Google Analytics verwendet das beispielsweise. Denkbar wäre aber auch ein lokaler eval(), bei dem man dem eval-Code Variablen zur Verfügung stellen will.  
                    
                  Mathias
                  
                  1. Hallo Mathias,

                    var foo = foo || [1, 2, 3];

                    
                    > >   
                    > > fehlerfrei in JSLint: "Global foo"  
                    >   
                    > Hingegen:  
                    >   
                    > (function () {  
                    > var foo = foo || [1, 2, 3];  
                    > alert(foo);  
                    > }());  
                    >   
                    > Error:  
                    > Problem at line 2 character 11: Unexpected 'foo'.  
                      
                    Naja, das könnte ja der Bug sein, der bei der yahoo-group geschildert wird bzw. die Inkonsitenz.  
                      
                    <https://forum.selfhtml.org/?t=204981&m=1388974>  
                      
                    Gruß, Robert aka  
                      
                    jobo
                    
        2. Hallo,

          var recur;
          recur = ...

          beruhigt jslint.

          Dann ist recur aber eine lokale Variable innerhalb der Funktion "recur" und verweist nicht auf sich selbst ("recur").

          bono345 hat schon recht. 'recur' wird dadurch nicht privater, als bei der Zuweisung während der Deklaration. Nach var recur; ist die Variable angelegt und kann dann auch benutzt werden, ohne dass JSLint meckert.

          Abgesehen davon ist der Code from Mr. JSLint persönlich.

          JSLint übertreibt's zuweilen mit den Meldungen.

          Nach einem for(var i=0; i<l; i++){ */...*/ } verweigert es knallhart die Weiterverarbeitung, weil 'i' innerhalb der Schleife definiert wird, statt am Anfang der Funktion. Das finde ich wirklich übertrieben, denn wenn man solche Laufvariablen immer außerhalb definiert, kann man eine solche Konstuktion nicht mehr einfach mit Copy&Paste woanders wiederverwenden, sondern muss immer aufpassen, das man auch die Variablendefinition mitnimmt.

          Aber Crocki schreibt ja auch ganz deutlich bei JSLint: "WARNING: JSLint will hurt your feelings."
          Da hast du den Salat ;)

          Gruß, Don P

          1. Hallo,

            Aber Crocki schreibt ja auch ganz deutlich bei JSLint: "WARNING: JSLint will hurt your feelings."
            Da hast du den Salat ;)

            Es verletzt ja nicht meine Gefühle. Sonst wäre es ja gegen die Forumscharta und ich hätte hier nix davon gepostet. Es fordert meinen Verstand heraus, bzw. das, was davon herauszufordern ist (;-).

            Seit kurzem weiß ich, dass es "use strict"; in Javascript gibt, weil das Teil des jslint-Quellcodes ist!

            Gruß

            jobo

  2. var memoizer = function (memo, formula) {
    var recur = function (n) {
    var result = memo[n];
    if (typeof result !== 'number') {
    result = formula(recur, n);
    memo[n] = result;
    }
    return result;
    };
    return recur;
    };

    Besser mit einer Named Function Expression:

    return function recur () {
       ...
       formula(recur, n);
       ...
    };

    Keine Ahnung, ob JSLint das erlaubt, das ist jedenfalls die saubere Variante, wenn man innerhalb einer Funktion auf sie selbst zugreifen will, außerhalb aber nicht.

    Ich verwende JSLint nicht. JSLint versteht JavaScript nicht hinreichend und 90% der Fehler und Warnungen sind für mich unbrauchbar zur Verbesserung des Codes.

    Mathias

    1. Hallo Matthias,

      var memoizer = function (memo, formula) {
      var recur = function (n) {
      var result = memo[n];
      if (typeof result !== 'number') {
      result = formula(recur, n);
      memo[n] = result;
      }
      return result;
      };
      return recur;
      };

      Besser mit einer Named Function Expression:

      return function recur () {
         ...
         formula(recur, n);
         ...
      };

      Keine Ahnung, ob JSLint das erlaubt, das ist jedenfalls die saubere Variante, wenn man innerhalb einer Funktion auf sie selbst zugreifen will, außerhalb aber nicht.

        
      var memoizer = function (memo, formula) {  
      	var recur;  
      	recur = function (n) {  
      		var result = memo[n];  
      		if (typeof result !== 'number') {  
      			result = formula(recur, n);  
      			memo[n] = result;  
      		}  
      		return result;  
      	};  
      	return recur;  
      };  
      
      

      Geht. Das Beispiel (ohne die Zeile 2 "var recur;") stammt ja aus Crockfords Vortrag (https://forum.selfhtml.org/?t=204924&m=1388501) bzw. aus den "good parts".

        
      var memoizer = function (memo, formula) {  
      	return function recur(n) {  
      		var result = memo[n];  
      		if (typeof result !== 'number') {  
      			result = formula(recur, n);  
      			memo[n] = result;  
      		}  
      		return result;  
      	};  
      };  
      
      

      Geht auch. Ohne "var recur;" zu definieren. Mit diese Definition kommt: Unused variable: recur 1 'memoizer';

      Ich verwende JSLint nicht. JSLint versteht JavaScript nicht hinreichend

      Eine Aussage die mich verwirrt. Crockford versteht Javascript nach meiner bisherigen Auffassung hinreichender als die meisten und kann dies nach meinem Empfinden obendrein auch noch ausgezeichnet kommunizieren. Insofern folgere ich daraus, dass seinem Programm Teile dieses Verständnisses wenn nicht gar sein komplettes Verständnis inne wohnt (;-).

      und 90% der Fehler und Warnungen sind für mich unbrauchbar zur Verbesserung des Codes.

      Ja, da lass ich mich als Nicht-JS-Experte gerne von einem Experten wie Crocky leiten. M.E. hat er für alle diese Einwände ganz gute Begründungen. Nicht selten basierend auf eigenen (schmerzhaften) Erfahrungen mit hartnäckigen Bugs. An den 10% ist mir gelegen (;-).

      Gruß

      Robert aka jobo

      1. Ich verwende JSLint nicht. JSLint versteht JavaScript nicht hinreichend

        Eine Aussage die mich verwirrt. Crockford versteht Javascript nach meiner bisherigen Auffassung hinreichender als die meisten

        JSLint ist eine Software. Diese Software hat nicht einmal einen vollständigen JavaScript-Parser, der einen abstrakten Syntaxbaum für die Tests verwendet. Viele JavaScript-Idiome versteht JSLint nicht oder falsch. Das führt zu verschiedenen Problemen. Die kann man im Bugtracker von JSHint nachlesen.

        Davon abgesehen erlaubt JSLint viele Programmiertechniken nicht, die m.M.n. völlig in Ordnung und durchaus guter Stil sind. Ich sehe keinen Sinn darin, dass sich jemand stundenlang an gegenstandlosen JSLint-Fehlermeldungen abarbeitet. Da sollte man lieber JavaScript lernen, um guten Code schreiben zu können. Da ist die Zeit besser investiert.

        Hast du etwa jetzt etwas gelernt durch diese JSLint-Fehlermeldung? Nur, weil du dich selbst auf die Suche begeben hast und hier Tipps bekommen hast. Weil du andere gefragt hast, die sich auskennen, im Gegensatz zu der Prüfsoftware.

        Der eine Tipp ist unsinnig, weil er in der Sache nichts verbessert, sondern eher verschlechtert, nur um JSLint zufriedenzustellen.
        Der andere verbessert den Code vielleicht sogar, allerdings kommt jetzt eine andere verwirrende JSLint-Meldung.
        Wohin soll das führen? Spätestens jetzt solltest du die Beschäftigung mit JSLint einstellen.

        Mathias

        1. Hallo Mathias,

          Der eine Tipp ist unsinnig, weil er in der Sache nichts verbessert, sondern eher verschlechtert, nur um JSLint zufriedenzustellen.
          Der andere verbessert den Code vielleicht sogar, allerdings kommt jetzt eine andere verwirrende JSLint-Meldung.
          Wohin soll das führen? Spätestens jetzt solltest du die Beschäftigung mit JSLint einstellen.

          Ich dachte eigentlich, das Programm verstehen zu wollen, als eine Paradebeispiel für JS-Programmierung und eines, dass sogar JSLint fehlerfrei passiert (https://forum.selfhtml.org/?t=204981&m=1389023).

          Gruß Robert aka

          jobo

          1. Ich dachte eigentlich, das Programm verstehen zu wollen, als eine Paradebeispiel für JS-Programmierung und eines, dass sogar JSLint fehlerfrei passiert (https://forum.selfhtml.org/?t=204981&m=1389023).

            Und was lernen wir daraus? Selbst Crockford schreibt guten und völlig fehlerfreien Code, der TROTZDEM nicht JSLint passiert.

            q.e.d.

            Mathias

            1. Hallo,

              Ich dachte eigentlich, das Programm verstehen zu wollen, als eine Paradebeispiel für JS-Programmierung und eines, dass sogar JSLint fehlerfrei passiert (http://forum.de.selfhtml.org/my/?t=204981&m=1389023).

              Und was lernen wir daraus? Selbst Crockford schreibt guten und völlig fehlerfreien Code, der TROTZDEM nicht JSLint passiert.

              q.e.d.

              Aber JSLint passiert JSLint. Und JSLint wird wohl guter Code sein. Insofern gibt es auch guten Code, der JSLint passiert (;-).

              Gruß

              jobo

        2. Hallo,

          JSLint ist eine Software. Diese Software hat nicht einmal einen vollständigen JavaScript-Parser, der einen abstrakten Syntaxbaum für die Tests verwendet. Viele JavaScript-Idiome versteht JSLint nicht oder falsch. Das führt zu verschiedenen Problemen. Die kann man im Bugtracker von JSHint nachlesen.

          Immerhin aber von JSLint abgeleitet:

          http://jshint.com/jshint.js

          aber was ist der Bugtracker von JSHint? http://jshint.com/

          Gruß

          jobo

          1. Die [Probleme] kann man im Bugtracker von JSHint nachlesen.

            Immerhin aber von JSLint abgeleitet:

            Ja, klar. Sonst hätte ich es in dem Kontext nicht erwähnt.

            aber was ist der Bugtracker von JSHint?

            https://github.com/jshint/jshint/issues

            Übrigens zur Erklärung: Ich stehe JSLint so kritisch gegenüber,

            • weil ich JavaScript relativ gut kann und er mich mit den dämlichen starren Regeln hauptsächlich nervt, meine Produktivität einschränkt und mich zu schlechter lesbaren und wartbaren Code zwingt, anstatt mich auf wirkliche Fehler in meinem Code hinzuweisen. Siehe beispielsweise Type Coercion.
            • weil ich viel CoffeeScript schreibe und damit ohnehin viele Fallstricke von JavaScript umgangen werden. Der generierte JS-Code ist m.W. auch JSLint-konform.
            • Viele verbleibende Fallstricke durch den ES5 Strict Mode abgedeckt werden, welchen ich für sämtlichen Code anschalte (und in entsprechenden Browsern teste).

            JSHint ist daher schon ein Schritt in die richtige Richtung. Allerdings habe ich das letztens ausprobiert und nur festgestellt, dass er (genauso wie JSLint) Function Expressions, Function Declarations und Hoisting nicht korrekt versteht. Ich glaube, das ist mittlerweile zumindest teilweise gefixt. Allerdings weicht das natürlich auch die Crockfordschen Regeln auf. Der verbietet die Nutzung von Function Declarations und deren Hoisting einfach und propagiert immer Function Expressions à la var f; f = function () {}; anstatt function f () {}. Mittlerweile hat JSHint soviele Konfigurationsoptionen, da müsste ich mir erst ein Set zusammenstellen, damit ich meinen Code testen kann. Ich bin skeptisch, ob dann noch wirkliche Fehler oder Best-Practise-Warnungen gefunden werden.

            Mathias

            1. Hallo Mathias,

              Die [Probleme] kann man im Bugtracker von JSHint nachlesen.

              Immerhin aber von JSLint abgeleitet:

              Ja, klar. Sonst hätte ich es in dem Kontext nicht erwähnt.

              aber was ist der Bugtracker von JSHint?

              https://github.com/jshint/jshint/issues

              Übrigens zur Erklärung: Ich stehe JSLint so kritisch gegenüber,

              • weil ich JavaScript relativ gut kann

              weiß ich

              und er mich mit den dämlichen starren Regeln hauptsächlich nervt, meine Produktivität einschränkt und mich zu schlechter lesbaren und wartbaren Code zwingt, anstatt mich auf wirkliche Fehler in meinem Code hinzuweisen. Siehe beispielsweise Type Coercion.

              naja, das kann man sicher so oder so sehen (;-).

              • weil ich viel CoffeeScript schreibe und damit ohnehin viele Fallstricke von JavaScript umgangen werden. Der generierte JS-Code ist m.W. auch JSLint-konform.

              (;-)

              • Viele verbleibende Fallstricke durch den ES5 Strict Mode abgedeckt werden, welchen ich für sämtlichen Code anschalte (und in entsprechenden Browsern teste).

              ja, den habe ich bei Crockfords jslint zum ersten mal gesehen.

              JSHint ist daher schon ein Schritt in die richtige Richtung. Allerdings habe ich das letztens ausprobiert und nur festgestellt, dass er (genauso wie JSLint) Function Expressions, Function Declarations und Hoisting nicht korrekt versteht.

              Hoisting heißt (http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/), dass ich lieber die variable am Anfang deklariere, weil sonst murx passiert, s. Link. Was ja wieder JSLint-konform wäre.

              Ich glaube, das ist mittlerweile zumindest teilweise gefixt. Allerdings weicht das natürlich auch die Crockfordschen Regeln auf. Der verbietet die Nutzung von Function Declarations und deren Hoisting einfach und propagiert immer Function Expressions à la var f; f = function () {}; anstatt function f () {}.

              Letzteres ist ja auch nicht zu unterscheiden von einer named function expression, wie ich auf der von dir verlinkten seite las.

              Ich kann schon verstehen, dass nicht jeder den Crockford-strict-mode mag. Ich verstehe aber durchaus, dass der Code dadurch nicht massiv schlechter wird. Vielleicht etwas anders. Einem Anfänger wie mir hilft das durchaus. Das Konstrukt

                
              var myFun = function innerName() {  
                  ...  
                  if(notFinished) {  
                       innerrName();  
                  }  
                  ...  
              }  
              
              

              ist mir erst durch JSLint aufgestoßen (natürlich kombiniert dann mit der Diskussion hier und u.U. bei der jslint_com.yahoogroup...).

              Gruß Robert aka

              jobo

              1. [latex]Mae  govannen![/latex]

                und er mich mit den dämlichen starren Regeln hauptsächlich nervt, meine Produktivität einschränkt und mich zu schlechter lesbaren und wartbaren Code zwingt, anstatt mich auf wirkliche Fehler in meinem Code hinzuweisen. Siehe beispielsweise Type Coercion.

                naja, das kann man sicher so oder so sehen (;-).

                Sehe ich auch so ;)

                Allerdings schadet es meiner Meinung nach in vielen Fällen durchaus nicht, === bzw. !== zu verwenden, insbesondere wenn man mit der Sprache und deren Besonderheiten eben noch nicht völlig vertraut ist. Die automatische Typumwandlung mit unerwartetem Resultat kann hier tw. mehr Schaden anrichten als die Verwendung (unnötiger) strikter Typvergleiche. Insofern gebe ich Crockford zum Teil recht mit seiner Empfehlung, es erst einmal möglichst so zu machen.

                Daß er dabei allerdings  *weit* (IMO) übers Ziel hinaus schießt (Zwang zu striktem Typvergleich und insbesondere(!) das Entfernen der Option, auch Vergleiche mit Typumwandlung zuzulassen), hat JSLint für mich ziemlich unbrauchbar werden lassen. Neben einigen anderen "Zwangs-Vorgaben", die nicht (mehr) abschaltbar sind. Dadurch erreicht Crockford nur, daß sich die Leute von JSLint abwenden, statt mit dessen Hilfe besseren Code zu schreiben.  Restriktives „Do as I say“ war noch nie eine gute Idee.
                In meinem Editor habe ich Javascript Lint eingebunden (ist zwar veraltet, für die Erkennung von grundsätzlichen und Flüchtigkeits-Fehlern aber durchaus gut geeignet) und dann lasse ich JSHint nachschauen (wobei _das_ wiederum ein paar Optionen zu viel völlig ausgebaut hat). JSLint schmeißt mir einfach zu viele Fehlermeldungen für Nicht-Fehler, als daß ich mich da noch durchwühlen wollte.

                Ich mag beispielsweise generell die "strict whitespace"-Option, weil ich Wert auf einen durchgängig gleichartigen Stil lege. Allerdings ist diese seit einiger Zeit nicht mehr nutzbar, da Crockford auf einmal auf die Idee kam, daß beispielsweise

                if (...) {  
                    // Code  
                }  
                else {  
                    // Code  
                }
                

                falsch ist. Jedes Vorkommen dieser Schreibweise wirft vier(!) Fehlermeldungen. Es ist fast unmöglich, die Meldungen, die ich tatsächlich haben möchte, im Wust dieser Falsch-Meldungen noch zu finden.

                Ich bin der Auffassung daß die Keywords »if« und »else« auf der gleichen Einrückungsebene zu stehen haben. JSLint akzeptiert aber ausschließlich die schreckliche Schreibweise

                if (...) {  
                    // Code  
                } else {  
                    // Code  
                }
                

                Warum ist (nicht abschltbar) (function () {})() falsch und (function () {}()) richtig?
                Weshalb ist i++ oder i-- in einfachen Schleifen ein Problem, nur weil ++/-- in ganz bestimmten Situationen in Verbindung mit Minifizierung zu einem werden _kann_? Warum muß ich aufwendige Konstrukte schreiben, wenn ich eigentlich nur ++i oder --i verwenden will?

                Ein Tool wie JSLint soll mir Fehler und potentielle Probleme melden, aber mir gefälligst nicht den Programmierstil aufzwingen, den Crockford wünscht. Da sage ich dann "Danke, aber nein danke".

                Stur lächeln und winken, Männer!
                Kai

                --
                Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken
                in Richtung "Mess up the Web".(suit)
                SelfHTML-Forum-Stylesheet
                1. Hallo,

                  falsch ist. Jedes Vorkommen dieser Schreibweise wirft vier(!) Fehlermeldungen. Es ist fast unmöglich, die Meldungen, die ich tatsächlich haben möchte, im Wust dieser Falsch-Meldungen noch zu finden.

                  Ich bin der Auffassung daß die Keywords »if« und »else« auf der gleichen Einrückungsebene zu stehen haben. JSLint akzeptiert aber ausschließlich die schreckliche Schreibweise

                  if (...) {

                  // Code
                  } else {
                      // Code
                  }

                    
                  Best practice im Zend Framework auch so.  
                    
                  
                  > Weshalb ist `i++`{:.language-javascript} oder `i--`{:.language-javascript} in einfachen Schleifen ein Problem, nur weil ++/-- in ganz bestimmten Situationen in Verbindung mit Minifizierung zu einem werden \_kann\_? Warum muß ich aufwendige Konstrukte schreiben, wenn ich eigentlich nur `++i`{:.language-javascript} oder `--i`{:.language-javascript} verwenden will?  
                    
                  weil du mit x += 1; drei Zeichen mehr hast als bei ++x; aber auf der sicheren Seite bist.  
                    
                  Es muss ja auch jeder selber wissen, wie sie/er sein Coding optimieren möchte. Coffeescript zB. wird ja hochgelobt von Crocky.  
                    
                  Gruß  
                    
                  jobo
                  
                  1. [latex]Mae  govannen![/latex]

                    Ich bin der Auffassung daß die Keywords »if« und »else« auf der gleichen Einrückungsebene zu stehen haben. JSLint akzeptiert aber ausschließlich die schreckliche Schreibweise

                    if (...) {

                    // Code
                    } else {
                        // Code
                    }

                    
                    >   
                    > Best practice im Zend Framework auch so.  
                      
                    Für mich eben aus oben genanntem Grund bad practice. Man muß eben nicht jeden Unsinn mitmachen. :)  
                    Außerdem war es in JSLint jahrelang erlaubt; es gibt neben der Eigenwilligkeit eines Crockford keinen wirklich sinnvollen Grund, das auf einmal zu ändern.  
                      
                    
                    > > Weshalb ist `i++`{:.language-javascript} oder `i--`{:.language-javascript} in einfachen Schleifen ein Problem, nur weil ++/-- in ganz bestimmten Situationen in Verbindung mit Minifizierung zu einem werden \_kann\_? Warum muß ich aufwendige Konstrukte schreiben, wenn ich eigentlich nur `++i`{:.language-javascript} oder `--i`{:.language-javascript} verwenden will?  
                    >   
                    > weil du mit x += 1; drei Zeichen mehr hast als bei ++x; aber auf der sicheren Seite bist.  
                      
                    Ich finde `a = foo[i += 1];`{:.language-javascript} seltsam. Das mag Gewöhnung sein. Ok, es wird für Leute, die den Unterschied zwischen `i++`{:.language-javascript} und `++i`{:.language-javascript} nicht kennen, deutlicher sein. Aber wenn ich `a = foo[i++];`{:.language-javascript} haben will, kann ich das JSLint-tauglich nicht mehr so einfach in einer Zeile schreiben, sondern muß `a = foo[i];(CRLF, Einrückungen)i += 1;`{:.language-javascript} schreiben.  
                      
                    Ansonsten: Crockford hätte auch genausogut testen können, was vor/hinter dem jeweiligen ++/-- steht und nur in \_den\_ Fällen eine Meldung ausgeben können, wenn potentielle Gefahr droht, statt ++/-- grundsätzlich zu bad practice zu machen.  
                      
                    Bei einfacher Verwendung wie `while (i--)`{:.language-javascript} oder auch `for (i = 0; i < 22; i++)`{:.language-javascript} sehe ich jedenfalls keine Gefahr.  
                      
                    Stur lächeln und winken, Männer!  
                    Kai
                    
                    -- 
                    Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken  
                    in Richtung "Mess up the Web".([suit](https://forum.selfhtml.org/?t=197497&m=1324775))  
                    [SelfHTML-Forum-Stylesheet](http://selfhtml.knrs.de/#h_stylesheet)
                    
            2. Hallo,

              Übrigens zur Erklärung: Ich stehe JSLint so kritisch gegenüber,

              • weil ich JavaScript relativ gut kann und er mich mit den dämlichen starren Regeln hauptsächlich nervt, meine Produktivität einschränkt und mich zu schlechter lesbaren und wartbaren Code zwingt, anstatt mich auf wirkliche Fehler in meinem Code hinzuweisen. Siehe beispielsweise Type Coercion.

              http://webreflection.blogspot.com/2010/10/javascript-coercion-demystified.html und dort die Antwort von "galambalazs":

              "Art, style and the case of Real Programmers

              While I think the technical content of this article is really valuable, I tend not to understand all the fuss about being hard on ourselves with coercion. I know it's all about Crockford and his recommendations.

              There are several points of this argument which I want to highlight. First off, nobody forces you to use JSLint, and noone ever said that it's more than a person’s opinion. I think we have misunderstandings about the language on a much larger scale than slight differences of opinion about JSLint can ever come into play.

              JSLint is not a syntax checker, it’s a Code Quality tool, and as such it evangelizes Crockford’s opinion on how one can write code that is more readable, maintainable and understandable to more people with less skill.

              „Programs must be written for people to read, and only incidentally for machines to execute."

              • Abelson & Sussman, SICP, preface to the first edition

              When you do Software Development you should always aim at readable code, because we vary in skills, talents and attitude to a language so there has to be some kind of convention of what we use. It’s especially true for high level languages. I would also like to quote Crockford on this:

              „The less we have to agree on, the more likely we can cooperate.”

              Code Quality is all about these two things. There is hardly any situation where coercion is algorithmically indispensable. The ones you’ve mentioned like null and undefined are just a matter of taste. The key to understand is that the amount of time writing the code is
              negligible compared to the time spent understanding other people’s code.

              Excluding „bad parts”, „evil parts” is not about mystifying the language, or mystifying ourselves. Sometimes I feel people think of this question as if Crockford had thought „it’s not for the masses, these things can only be understood by me”. And here come the smart challengers who prove to understand deep things about the language.

              Crockford has always been clear on this. He wants to keep the language simple to understand, simple to work with. This can be achieved by ignoring language constructs or style of programming that is error prone or hard to understand/debug.
              04 December, 2010 15:53"

              Gruß

              jobo

              1. Hallo,

                mir ist schon klar, worauf JSLint abzielt und was der Hintergrund ist (siehe auch http://molily.de/weblog/javascript-objektabfragen): JavaScript als gleichzeitig populärste und am meisten missverstandene Sprache, die von Laien oft als erste Programmiersprache geschrieben wird. Die JSLint-Regeln sollen einem haarige Details und Fallstricke von JavaScript verstecken, damit verschiedene Leute mit unterschiedlichem Wissen zusammenarbeiten können.

                Diese Motivation kann ich natürlich nachvollziehen, allerdings sehe ich in der Beschäftigung mit JSLint z.T. mehr Sprengstoff und WTF-Potenzial als in der unumgänglichen Beschäftigung mit JavaScript/ECMAScript selbst. In den Fachartikeln, die ich für Anfänger schreibe, versuche ich die nötigen Grundlagen zu vermitteln, um Type-Coercion beherrschen zu können. In meiner professionellen Arbeit kann ich Kollegen auf die ECMAScript-Spec und auf gute Fortgeschrittenen-Artikel verweisen.

                Mathias

                1. Hallo,

                  Hallo,

                  mir ist schon klar, worauf JSLint abzielt und was der Hintergrund ist (siehe auch http://molily.de/weblog/javascript-objektabfragen): JavaScript als gleichzeitig populärste und am meisten missverstandene Sprache, die von Laien oft als erste Programmiersprache geschrieben wird. Die JSLint-Regeln sollen einem haarige Details und Fallstricke von JavaScript verstecken, damit verschiedene Leute mit unterschiedlichem Wissen zusammenarbeiten können.

                  Es ist offenbar auch Geschmacksache. In dem vormals verlinkten Artikel http://webreflection.blogspot.com/2010/10/javascript-coercion-demystified.html wird ja auch darauf eingegangen. Aber mir leuchtet ein, dass diese truthyness zum Fallstrick werden kann. a === undefined || a === null aber nicht. Das leuchtet doch sofort und komplett ein, was da gemeint ist. Während a == null möglicherweise nicht das ausdrückt, was der Autor gemeint hat, wenn ers nicht kapiert hat oder aber nicht ausdrückt, was gemeint ist, für jemanden, der noch nicht ganz soweit ist. So immerhin verstand ich die zitierte Argumentation. Dass das nicht jedermans/-fraus Sache ist, ist ja offensichtlich und zu Teilen ja auch nachvollziehbar, insofern dann eben Geschmackssache.

                  Gruß

                  jobo

      2. Hallo,

        Besser mit einer Named Function Expression:

        return function recur () {
           ...
           formula(recur, n);
           ...
        };

        Keine Ahnung, ob JSLint das erlaubt, das ist jedenfalls die saubere Variante, wenn man innerhalb einer Funktion auf sie selbst zugreifen will, außerhalb aber nicht.

        var memoizer = function (memo, formula) {
        return function recur(n) {
        var result = memo[n];
        if (typeof result !== 'number') {
        result = formula(recur, n);
        memo[n] = result;
        }
        return result;
        };
        };

        
        >   
          
        In der jslint\_com@yahoogroups.com bekam ich noch den Hinweis dazu:  
          
          
        That would be using the language as designed:  
          
        ECMA-262 [3rd and 5th editions]: The \*Identifier \*in a \*FunctionExpression \*can  
        be referenced from inside the \*FunctionExpression's FunctionBody \*to allow  
        the function to call itself recursively. However, unlike in a \*  
        FunctionDeclaration\*, the \*Identifier \*in a \*FunctionExpression \*cannot be  
        referenced from and does not affect the scope enclosing the \*  
        FunctionExpression\*.  
          
          
        Gruß  
          
        jobo