Hallo Gunnar
function escapeHtml(unsafe) {
Hm, eine globale Funktion?
Ob die Funktion global, ist hängt davon ab, wo sie definiert wird. Das lässt sich ja aus dem Schnippsel nicht ableiten. Grundsätzlich ist es aber natürlich nicht falsch, auch hier über die Kapselung des Codes nachzudenken. Die einfachste Methode das Ziel zu erreichen ist wohl, nur lexikalische Deklarationen (const
oder let
) zu verwenden und das ganze Programm in einem Anweisungsblock auszuführen, also etwa so:
// counter.js
{
const escapeHTML = unsafe => {};
⋮
const createCounter = (online, visits) => {};
}
Da es sich bei dem Besucherzähler nur um ein Komfortfeature handelt, könnte man auch darüber nachdenken, das Programm als Modul einzubinden.
<script type="module" src="counter.js"></script>
Wird ein Skript auf diese Weise eingebunden, dann sind prinzipiell alle im globalen Gültigkeitsbereich vorgenommenen Deklarationen auf eben dieses Skript beschränkt. Sie leaken nicht in den Scope von anderen Modulen oder Skripten. Der Browsersupport für Module liegt heute soweit ich weiß bei über achtzig Prozent. Ich finde das ist ein Fall, wo man über die Verwendung ohne Netz und doppelten Boden nachdenken kann.
Wäre das nicht sauberer?
String.prototype.escapeHtml = function () { return this .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); };
Und statt
escapeHtml(visits)
dannvisits.escapeHtml()
.
Ich halte das Verändern von eingebauten Objekten für schlechte Praxis. Bei diesen Objekten handelt es sich um geteilte Ressourcen und wie immer in solchen Fällen muss sichergestellt werden, dass sich die Nutzer dieser Ressourcen nicht in die Quere kommen. Als Entwickler erwarte ich die eingebauten Objekte so vorzufinden, wie sie standardisiert und dokumentiert sind. Wenn jedes eingebundene Skript die eingebauten Objekte nach belieben an die eigenen Bedürfnisse anpasst, dann ist das nicht mehr gewährleistet und es ist nur eine Frage der Zeit, bis es zu unvorhersehbaren Fehlern kommt.
Natürlich ist es unwahrscheinlich, dass ein anderes Programm ebenfalls eine Methode mit dem Namen escapeHtml
auf String.prototype
definieren will und diese Methode mit deiner Definition nicht kompatibel ist. Indem du dieses eingebaute Objekt manipulierst, handelst du aber nicht nach einer Maxime von der man wollen kann, dass sie allgemeines Gesetz werde. Es ist meiner Meinung nach eine gute Konvention, die gemeinsam genutzten Objekte nicht zu verändern.
Wenn man Standardobjekte unbedingt anpassen möchte, dann ist die bessere Vorgehensweise, eine von dem jeweiligen Typ abgeleitete Klasse zu erstellen. Im vorliegenden Fall ist das zwar nicht wirklich praktikabel, da es sich bei Strings nicht um Objekte sondern um einen primitiven Datentyp handelt, und wir die Werte darüber hinaus auch nicht selbst produzieren, aber in vielen Fällen erreicht man damit sein Ziel, ohne dabei die Ausführung von anderen Programmen zu gefährden.
Viele Grüße,
Orlok