Signatur
Beschreibung
Die Methode cmp() des Interfaces IDBFactory (in der Praxis meist über indexedDB.cmp() aufgerufen) vergleicht zwei Werte genau so, wie IndexedDB Schlüssel intern vergleicht. Das Ergebnis zeigt, ob der erste Schlüssel kleiner, gleich oder größer als der zweite ist. So erfahren Sie, in welcher Reihenfolge Datensätze in einem Object Store oder Index abgelegt werden und ob zwei Schlüssel als identisch gelten.
IndexedDB kennt eine feste Typ-Reihenfolge: Number < Date < String < Binärdaten (ArrayBuffer, typisierte Arrays, DataView) < Array. Innerhalb eines Typs wird nach Wert verglichen. Zeichenketten vergleicht IndexedDB anhand ihrer UTF-16-Codeeinheiten, also nicht sprachabhängig. Arrays werden Element für Element verglichen, deshalb eignet sich die Methode gut für zusammengesetzte Schlüssel.
Typische Einsatzfälle:
- Clientseitig vorab sortierte Daten in derselben Reihenfolge erzeugen, die auch ein Cursor liefern würde.
- Schlüsselbereiche (
IDBKeyRange) prüfen, bevor man sie anlegt. Ist die Untergrenze größer als die Obergrenze, wirftIDBKeyRange.bound()einen Fehler. - Prüfen, ob ein Wert überhaupt ein gültiger Schlüssel ist. Bei ungültigen Werten wirft
cmp()eine Ausnahme.
Der Aufruf läuft synchron und öffnet keine Datenbank. Sie brauchen dafür weder eine Transaktion noch eine offene Verbindung.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $first Pflicht | number|Date|string|ArrayBuffer|ArrayBufferView|Array | Erster Schlüssel, der verglichen wird. Er muss ein gültiger IndexedDB-Schlüssel sein. | |
| $second Pflicht | number|Date|string|ArrayBuffer|ArrayBufferView|Array | Zweiter Schlüssel, der verglichen wird. Auch er muss ein gültiger IndexedDB-Schlüssel sein. |
Rückgabewert
-1, wenn first kleiner als second ist, 0 bei Gleichheit und 1, wenn first größer ist.Beispiele
Grundlegende Vergleiche
console.log(indexedDB.cmp(1, 2)); // kleiner
console.log(indexedDB.cmp('abc', 'abc')); // gleich
console.log(indexedDB.cmp('b', 'a')); // größer
// Typ-Reihenfolge: Number < Date < String < Binär < Array
console.log(indexedDB.cmp(9999, new Date(0)));
console.log(indexedDB.cmp('zzz', [0]));
// Strings nach UTF-16-Codeeinheiten: 'Z' (90) < 'a' (97)
console.log(indexedDB.cmp('Z', 'a'));
Zusammengesetzte Schlüssel (Arrays) vergleichen
// z. B. Index über [jahr, kategorie]
console.log(indexedDB.cmp([2024, 'buch'], [2024, 'auto'])); // 2. Element entscheidet
console.log(indexedDB.cmp([2023, 'zoo'], [2024, 'auto'])); // 1. Element entscheidet
console.log(indexedDB.cmp([1], [1, 2])); // kürzeres Präfix ist kleiner
Daten in IndexedDB-Reihenfolge sortieren
const keys = ['b', 3, [1], new Date(0), 'a', 1];
// Gleiche Reihenfolge, die ein Cursor über diese Schlüssel liefern würde
const sorted = [...keys].sort((a, b) => indexedDB.cmp(a, b));
console.log(sorted.map(k => (k instanceof Date ? 'Date' : JSON.stringify(k))));
Gültigkeit von Schlüsseln prüfen und Key-Range absichern
const isValidKey = (value) => {
try {
indexedDB.cmp(value, 0);
return true;
} catch (err) {
if (err.name === 'DataError') return false;
throw err;
}
};
console.log(isValidKey('user-42')); // true
console.log(isValidKey(null)); // false
console.log(isValidKey(true)); // false
console.log(isValidKey(NaN)); // false
console.log(isValidKey(new Date('kaputt'))); // false
// Grenzen vor IDBKeyRange.bound() in die richtige Reihenfolge bringen
const safeBound = (a, b) =>
indexedDB.cmp(a, b) <= 0 ? IDBKeyRange.bound(a, b) : IDBKeyRange.bound(b, a);
const range = safeBound('m', 'c');
console.log(range.lower, range.upper);
// Wichtig · Fallstricke
- Ausnahmen: Ist einer der beiden Werte kein gültiger Schlüssel, wirft
cmp()eineDOMExceptionmit dem NamenDataError. Ungültig sind zum Beispielnull,undefined,boolean, einfache Objekte,NaN, ungültigeDate-Objekte sowie Arrays mit ungültigen oder zirkulären Elementen. Übergeben Sie weniger als zwei Argumente, wird einTypeErrorgeworfen. - Keine sprachabhängige Sortierung: Strings werden nach UTF-16-Codeeinheiten verglichen. Deshalb gilt
'Z' < 'a'und'ä' > 'z'. Für eine Sortierung, die Menschen erwarten, verwenden SieIntl.CollatoroderlocaleCompare(). Beachten Sie aber, dass IndexedDB selbst immer nach Codeeinheiten sortiert. - Typen werden nicht umgewandelt:
indexedDB.cmp(1, '1')ergibt-1und nicht0. Zahl und String sind also verschiedene Schlüssel. -0und0gelten als gleich.Infinityund-Infinitysind gültige Schlüssel.- Binärschlüssel (
ArrayBufferund Views) werden in allen aktuellen Browsern unterstützt, in sehr alten Versionen aber nicht. - Die Methode steht auch in Web Workers zur Verfügung (
self.indexedDB.cmp()). In manchen privaten Browser-Modi kannindexedDBeingeschränkt sein.cmp()selbst funktioniert aber ohne Speicherzugriff.