Abhilfe zum Java Script
Original bei Douglas Crockford
Die Programmiersprache Java Script leidet unter vorzeitiger Standardisierung (premature standardization). Sie wurde in aller Eile auf den Markt gebracht und gewann sofort eine breite Masse an Benutzern. Bald darauf folgte der formale internationale Standard. So blieb während ihrer Entwicklung keine Zeit, um die Sprache ein wenig zu glätten. Im Endresultat hat sie so noch immer einige rauhe Stellen.
Einige der Probleme können wir leicht vermeiden, indem wir Fehlentwicklungen wie das With-Statement nicht verwenden. Ein Lint-Programm kann ebenfalls hilfreich sein, um die scharfen Ecken und Kanten des Java Scripts fernzuhalten.
Einige Feature-Versäumnisse können korrigiert werden, indem wir neue Funktionen and grundlegende Methoden zu unserem Standard-Programmier-Toolkit hinzufügen. Genau das ist es, was wir hier tun werden. Es gibt einige Funktionen, von denen ich glaube, dass sie im Standard hätten enthalten sein sollen und in jeder Anwendung gebraucht werden. Glücklicherweise ist JavaScript eine derart ausdrucksvolle Sprache, dass wir die Versäumnisse lokal nachholen können.
JavaScript wird am häufigsten in Web-Applications gebraucht, und noch immer gibt es ein Erbe der Inkompatibilität, das noch aus den Browser-Kriegen stammt. Eine Zeit lang fügten Netscape und Microsoft wie wahnsinnig Features zu ihren Browsern hinzu, manchmal, indem sie einander nur kopierten, manchmal, indem sie proprietäre Hooks einpflanzten, manchmal, indem sie unkorrekterweise eine zukünftige ECMA Script-Sprachen-Spezifizierung erwarteten.
Typerkennung
Da JavaScript eine Sprache schwacher Typisierung ist, ist es manchmal notwendig, einen Wert zu prüfen, um seine Art zu bestimmen (dies ist manchmal bei Sprachen starker Typisierung ebenfalls nötig). JavaScript stellt einen typeof-Operator zur Verfügung, um dies zu erleichtern, doch typeof hat Probleme.
Object |
'object' |
Array |
'object' |
Function |
'function' |
String |
'string' |
Number |
'number' |
Boolean |
'boolean' |
null |
'object' |
undefined |
'undefined' |
typeof [] produziert 'object' statt 'array'. Das ist nicht komplett falsch, da Arrays in JavaScript von Objekten stammen, doch hilfreich ist es nicht. typeof null produziert 'object' statt 'null'. Das ist komplett falsch.
Wir können dies korrigieren, indem wir unsere eigene typeOf-Funktion definieren. Diese können wir anstelle des defekten typeOf-Operators benutzen.
isEmpty(v)
isEmpty(v) erwidert true, wenn v ein Objekt ist, das keine zählbaren Elemente enthält.
String-Methoden
JavaScript bietet einige nützliche Methoden für Strings, lässt aber andere wichtige aus. Glücklicherweise erlaubt JavaScript es uns, neue Methoden zu den grundlegenden hinzuzufügen.
entityify()
entityify() produziert einen String, in dem '<', '>' und '&' mit ihren HTML entity-Äquivalenten ersetzt werden. Dies ist notwendig, um beliebige Strings in HTML-Texte zu setzen. Folgendermaßen sieht es aus:
"if (a < b && b > c) {".entityify()
produziert
"if (a < b && b > c) {"
quote()
quote() produces a quoted string. This method returns a string that is like the original string except that it is wrapped in quotes and all quote and backslash characters are preceded with backslash.
quote() produziert einen quoted-String. Diese Methode ergibt einen String, der wie der originale String ist, außer, dass er in Quotes (Zitatzeichen) eingewickelt ist. Allen Quote- und Backslash-Zeichen sind Backslashes vorangestellt.
supplant(object)
supplant() ergibt am String Variablen-Ersetzungen. Es scannt den String durch und sucht nach Expressions, die in { }-Klammern stehen. Wenn eine Expression gefunden wurde, benutzen Sie es als Key auf das Objekt, und wenn der Key eine String- oder Number Value hat, wird es anstelle der Klammer-Expression benutzt und wiederholt sich. Dies ist nützlich, um automatisch URLs zu reparieren. Folgendermaßen:
param = {domain: 'valvion.com', media: 'http://media.valvion.com/'};
url = "{media}logo.gif".supplant(param);
produziert eine url, die "http://media.valvion.com/logo.gif" enthält
trim()
Die trim()-Methode entfernt Whitespace-Zeichen von Anfang und Ende eines Strings.
Deployment
Sie können diese Funktion in Ihre Code-Bibliothek packen und sie individuell in Ihre Projekte kopieren, wie Sie sie brauchen. Oder Sie können sie in eine einzelne Datei packen, welche Sie in all Ihre Projekte aufnehmen, sodass Sie immer darauf zählen können, eine vertraute Plattform zum Arbeiten zu haben. Vergewissern Sie sich, die Datei immer mit JSMin zu verarbeiten, um die Download-Zeit zu reduzieren. Sie können auch Ihre eigenen Toolkit-Funktionen aufnehmen.
Source
Im folgenden Quellcode waren die Prioritäten Beweglichkeit und Komptaktheit.
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (value instanceof Array) {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
Die obige typeOf-Funktion wird nicht nur Arrays erkennen, die im selben Kontext (oder Fenster oder Frame) kreiert werden. JavaScript bietet keine unfehlbaren Mechanismen, um Arrays von Objekten zu unterscheiden. Wenn wir also Arrays erkennen wollen, die in einem anderen Frame erstellt werden, müssen wir etwas Komplizierteres tun:
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (typeof value.length === 'number' &&
!(value.propertyIsEnumerable('length')) &&
typeof value.splice === 'function') {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
function isEmpty(o) {
var i, v;
if (typeOf(o) === 'object') {
for (i in o) {
v = o[i];
if (v !== undefined && typeOf(v) !== 'function') {
return false;
}
}
}
return true;
}
String.prototype.entityify = function () {
return this.replace(/&/g, "&").replace(//g, ">");
};
String.prototype.quote = function () {
var c, i, l = this.length, o = '"';
for (i = 0; i < l; i += 1) {
c = this.charAt(i);
if (c >= ' ') {
if (c === '\\' || c === '"') {
o += '\\';
}
o += c;
} else {
switch (c) {
case '\b':
o += '\\b';
break;
case '\f':
o += '\\f';
break;
case '\n':
o += '\\n';
break;
case '\r':
o += '\\r';
break;
case '\t':
o += '\\t';
break;
default:
c = c.charCodeAt();
o += '\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}
}
}
return o + '"';
};
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, "");
};