Für Leute, die neugierig auf die v8-Implementierung sind, ist hier die Quelle . Da unshifteine beliebige Anzahl von Argumenten verwendet wird, verschiebt sich das Array selbst, um alle Argumente aufzunehmen.
UnshiftImplendet Aufruf AddArgumentsmit einem start_positionvon AT_STARTihm zu diesem welche Tritte elseAussage
Isolate* isolate = receiver->GetIsolate();
Subclass::MoveElements(isolate, receiver, backing_store, add_size, 0,
length, 0, 0);
und bringt es zum MoveElements.
static void MoveElements(Isolate* isolate, Handle<JSArray> receiver,
Handle<FixedArrayBase> backing_store, int dst_index,
int src_index, int len, int hole_start,
int hole_end) {
Heap* heap = isolate->heap();
Handle<BackingStore> dst_elms = Handle<BackingStore>::cast(backing_store);
if (len > JSArray::kMaxCopyElements && dst_index == 0 &&
heap->CanMoveObjectStart(*dst_elms)) {
*dst_elms.location() =
BackingStore::cast(heap->LeftTrimFixedArray(*dst_elms, src_index))
->ptr();
receiver->set_elements(*dst_elms);
hole_end -= src_index;
DCHECK_LE(hole_start, backing_store->length());
DCHECK_LE(hole_end, backing_store->length());
} else if (len != 0) {
WriteBarrierMode mode = GetWriteBarrierMode(KindTraits::Kind);
dst_elms->MoveElements(heap, dst_index, src_index, len, mode);
}
if (hole_start != hole_end) {
dst_elms->FillWithHoles(hole_start, hole_end);
}
}
Ich möchte auch darauf hinweisen, dass v8 ein unterschiedliches Konzept hat, element kindsje nachdem, was das Array enthält. Dies kann auch die Leistung beeinträchtigen.
Es ist schwer zu sagen, wie hoch die Leistung ist, da es ehrlich gesagt davon abhängt, welche Arten von Elementen übergeben werden, wie viele Löcher sich im Array befinden usw. Wenn ich dies genauer durchforste, kann ich vielleicht eine endgültige Antwort geben, aber im Allgemeinen gehe ich davon aus Da unshiftmehr Platz im Array reserviert werden muss, können Sie im Allgemeinen davon ausgehen, dass es O (N) ist (wird abhängig von der Anzahl der Elemente linear skaliert), aber jemand korrigiert mich bitte, wenn ich falsch liege.