So legen Sie programmatisch die Länge einer Funktion fest

8

Die Eigenschaft length der Funktionen gibt an, wie lange das Argument "expected" ist Liste ist:

%Vor%

Es handelt sich jedoch um eine schreibgeschützte Methode:

%Vor%

Gibt es eine Möglichkeit, diese Länge programmgesteuert festzulegen? Der nächste, den ich bisher gesehen habe, ist der Konstruktor Function:

%Vor%

Allerdings ist die Verwendung von Function im Wesentlichen die gleiche wie eval und wir wissen alle, wie schlecht das ist. Welche anderen Möglichkeiten habe ich hier?

    
nickf 06.09.2011, 08:01
quelle

5 Antworten

5

Für jetzt ist hier die beste Lösung, die ich mir vorstellen konnte.

%Vor%

Beispielverwendung:

%Vor%

Ich persönlich zittere immer, wenn ich beim Programmieren Kopieren und Einfügen verwende, also wäre ich sehr froh, von besseren Möglichkeiten zu hören.

Aktualisieren

Ich dachte an eine Methode, die für jede beliebige Größe funktionieren könnte, im Gegensatz zum obigen Beispiel, das durch die Anzahl der Male, die Sie kopieren und einfügen möchten, begrenzt ist. Im Wesentlichen erstellt es dynamisch eine Funktion (mit new Function ), die eine Funktion der richtigen Größe zurückgibt, die dann nur zu der Funktion weitergeleitet wird, die Sie ihr übergeben. Ja, das tut dir weh. Wie auch immer, ich dachte, ich würde es mit dem oben genannten vergleichen ...

Ссылка (Sie können dort auch den 'bösen' Code sehen).

Die böse Methode ist viele hundert Mal langsamer als die hacky Copypasta-Methode, also los geht's.

    
nickf 06.09.2011, 08:34
quelle
4

Es stellt sich heraus, dass die Eigenschaft length für Funktionen konfigurierbar , was bedeutet, dass Sie .defineProperty verwenden können um den Wert der Länge einer Funktion zu ändern. Beispiel:

%Vor%

Dies funktioniert in der neuesten Version von Chrome und Firefox, funktioniert aber nicht in Safari (v9.1.1).

    
Xavi 05.06.2016 18:29
quelle
3

Ich mache etwas, wonach Sie fragen, indem Sie ungefähr Folgendes verwenden:

%Vor%

Dies macht einen Funktionskonstruktor, aber in einer streng begrenzten Weise und nur einmal pro Funktionsgröße, um einen Funktions-Wrapper (der für diese Größe zwischengespeichert wird) zu erstellen, danach verwende ich wrapper.bind ( real_function), um die Implementierung als Funktion Ausdruck / Objekt bereitzustellen.

Die Vorteile sind, dass jede Größe unterstützt wird und wir nicht schwer die Funktionsdefinitionen kodieren, aber tatsächliche Funktionsimplementierungen werden nie in einer "eval" -ähnlichen Weise gemacht und die an den Funktionskonstruktor übergebene Zeichenkette ist immer dieselbe.

%Vor%

Ich bin sicher, dass es viele Gründe dafür gibt, dass dies auch schlecht ist (beginnend mit der Verwendung von Bindebedeutungsfunktionen, die auf diese Weise erzeugt werden, können nicht an ein Objekt gebunden werden), aber es ist in Situationen nützlich, in denen es möglich sein muss um eine Funktion beliebiger Länge dynamisch zu erstellen.

    
Barnabee 22.10.2014 15:05
quelle
1

Nach dem ECMA Script Standard, Revision 5.1 auf Seite 103, der .length -Parameter auf einem Function -Objekt ist nicht beschreibbar, daher wird es gesetzt, wenn die Funktion deklariert und nicht änderbar ist (falls pro Spezifikation implementiert).

Somit ist die einzige Möglichkeit, eine Funktion mit einem bestimmten .length bei Bedarf zu erstellen, ein Bündel von Funktionen unterschiedlicher Länge zu sein (wie es nickf vorschlägt), ein Function-Objekt zu erstellen (wie Sie bereits erwähnt haben) ) oder verwende eval() mit einer dynamisch erzeugten Zeichenkette. Ich weiß nicht, welches Problem du eigentlich lösen willst, aber ich persönlich finde nichts falsch daran, eval () zu benutzen, wenn du die Quelle des Codes kennst, mit dem du es benutzt und eine Möglichkeit hast, es zu überprüfen oder zu wissen was es darin haben wird oder nicht. In diesem Fall stellt das programmatische Generieren einer bestimmten Anzahl von Parametern in einer Zeichenfolge vor dem Aufrufen von eval () kein Sicherheitsrisiko dar, das mir bekannt ist.

Wenn das alles Ihr eigener Code ist, können Sie einfach eine neue Eigenschaft für die Funktion .dynLength erstellen, die änderbar ist, und sie auf das einstellen, was Sie wollen, und Ihren Code dazu verwenden.

    
jfriend00 06.09.2011 08:40
quelle
1

Es gibt ein npm Modul Nützlichkeit was macht was du willst:

%Vor%     
tomekwi 05.08.2015 10:37
quelle

Tags und Links