Einige verschiedene Kenntnisse über Funktionen in JS

1. Machen Sie deutlich, dass eine Funktion tatsächlich ein Objekt ist, sodass der Funktionsname tatsächlich eine Variable ist, die einen Funktionsobjektzeiger enthält.
2. Pfeilfunktionen können weder Argumente, super und new.target verwenden, noch können sie als Konstruktoren verwendet werden, und es gibt kein Prototypattribut.
3. Jede Funktion stellt ein schreibgeschütztes Namensattribut bereit, das den Funktionsnamen zurückgibt, wobei die Pfeilfunktion eine leere Zeichenfolge und die anonyme Funktion „anonymous“ zurückgibt.
4. Der Typ und die Anzahl der von der Funktion übergebenen Parameter sind unbegrenzt. Die Parameter werden nur der Einfachheit halber geschrieben und können im Argumentobjekt abgerufen werden.
5. Wenn Sie den Wert in Argumenten ändern, wird auch der entsprechende benannte Parameter entsprechend geändert. Gemäß der vierten Ausgabe von „Javascript Advanced Programming“ hat eine Änderung des benannten Parameters keinen Einfluss auf den Wert in Argumenten, sondern auf den test Das Ergebnis wird sein:

function testArguments (a, b) {
    
    
  arguments[0] = 1
  console.log(a,b)
  b = 4
  console.log(arguments)
}
testArguments(2,3)
//1 3
//[Arguments] { '0': 1, '1': 4 }

Wenn der Standardwert des Parameters festgelegt wird, wirkt sich die Änderung des benannten Parameters außerdem nicht auf den Wert in den Argumenten aus, und die Änderung des Werts in den Argumenten wirkt sich nicht auf den benannten Parameter aus, d. h. die Argumente basieren immer auf die empfangenen Parameter:

function testArguments (a, b = 100) {
    
    
  arguments[0] = 1 //arguments[0]修改了, 但a不受影响
  console.log(a,b)
  b = 4  //a b的值改了, 但arguments[1]的值不受影响
  console.log(a, b, arguments)
}
testArguments(2,3)
//2 3
//2 4 [Arguments] { '0': 1, '1': 3 }

Nun, es stimmt zwar, dass das Ändern der benannten Parameter, wie es im Buch heißt, keinen Einfluss auf den Wert in den Argumenten hat, aber warum wird die Änderung des Werts der Argumente nicht mit den benannten Parametern synchronisiert? Ich hoffe, jemand hat eine Antwort. .

6. Der erweiterte Parameter wird beim Aufruf der Funktion verwendet, was bedeutet, dass das eingehende Array in Parameter erweitert wird. Der Sammlungsparameter wird beim Definieren der Funktion verwendet und gibt an, dass mehrere Eingabedaten in ein Array integriert werden.
7. arguments.callee gibt den Funktionszeiger zurück, was bedeutet, dass diese Funktion über arguments.callee aufgerufen werden kann. Wenn diese Funktion extern umgeschrieben wird, wird die umgeschriebene Funktion aufgerufen, wenn der ursprüngliche Funktionsname zum Aufrufen verwendet wird. Bei Verwendung von Argumenten .callee ruft die ursprüngliche Funktion auf.
8. funName.caller kann das Objekt zurückgeben, das die Funktion aufgerufen hat.
9. Es gibt keine Überladung, da es keine Parameterbeschränkungen gibt. Wenn Sie eine Überladung simulieren möchten, können Sie Argumente verwenden, um die Eingabeparameter zu beurteilen.
10. new.target kann erkennen, ob die Funktion normal oder über new aufgerufen wird. Wenn es von new aufgerufen wird, verweist new.target auf den aufgerufenen Konstruktor, andernfalls ist es undefiniert.
11. Wenn die Funktion den Kontext des Aufrufs nicht angibt, handelt es sich um ein Fenster, das im strikten Modus undefiniert ist.
12. Tail Call bedeutet, dass der Wert der Funktionsrückgabe auch eine Funktion ist. Gemäß dem Mechanismus vor ES6 werden bei mehreren Verschachtelungsebenen die aufgerufenen Funktionen Schicht für Schicht in den Stapel verschoben und dann Schicht für Schicht aus dem Stapel entnommen. Nach der ES6-Optimierung stellte er fest, dass eine Rückgabe erforderlich ist und der Rückgabewert auch eine Funktion ist. Dann kann die ursprüngliche Funktion direkt vom Stapel entfernt werden und nur die aktuell ausgeführte Funktion beibehalten werden. Die optimale Tail-Call-Optimierung weist jedoch auch bestimmte Einschränkungen auf. Beispielsweise können nach der Rückgabefunktion keine anderen Vorgänge ausgeführt werden, z. B. die Rückgabe von fun.toString (), und die Rückgabe darf kein Abschluss sein. In diesen Situationen wird der Optimierungseffekt nicht erzielt .
Beispiele, die optimiert werden können:

function fib(n) {
    
    
  if (n < 2) return n
  return fib(n - 1) + fib(n - 2)
}
//这里虽然是尾调用,但并没有达到优化的效果,因为返回的结果还要相加
//如果求fib(1000)浏览器就承受不住了
//优化的方法有两个,换成非递归,或者将该递归拆成两个函数,一个是基础框架,一个执行递归
function fib(n) {
    
    
  return fibImpl(0, 1, n)
}
function fibImpl(a, b, n) {
    
      //递归
  if (n == 0) return a
  return fibImpl(b, a + b, n - 1)
}

Nach der Optimierung kann fib(1000) in Sekundenschnelle Ergebnisse liefern.
13. Interne Funktionen können nicht direkt auf diese und Argumente externer Funktionen zugreifen. Dies liegt daran, dass jede Funktion beim Aufruf zwei spezielle Variablen erstellt, nämlich this und arguments. Wenn Sie auf die externe Variable zugreifen möchten, können Sie die externe Variable mit einem anderen Namen speichern, z. B. let that = this, so Sie können dies der externen Funktion erhalten, wenn sich das Sub in der internen Funktion befindet (da es keinen Namenskonflikt gibt). (Ich habe es vorher nur so verwendet, ich habe nicht darüber nachgedacht, warum.) Dies wird häufig in verwendet Schließungen.
14. Abschlüsse beziehen sich auf Funktionen, die auf Variablen im Gültigkeitsbereich einer anderen Funktion verweisen, die normalerweise in verschachtelten Funktionen implementiert ist.
15. Wenn eine Funktion aufgerufen wird, wird ein Ausführungskontext für den Funktionsaufruf erstellt und eine Bereichskette erstellt. Das Live-Objekt für diese Funktion wird dann mit Argumenten und benannten Parametern initialisiert. Das aktive Objekt der äußeren Funktion ist das zweite Objekt in der Gültigkeitsbereichskette der inneren Funktion. Diese Bereichskette umfasst alle aktiven Objekte, die die aufrufende Funktion enthalten, bis der globale Ausführungskontext beendet wird.
16. Obwohl es in JS kein Konzept für private Objekteigenschaften gibt, können Abschlüsse verwendet werden, um öffentliche Methoden zu implementieren und auf Variablen zuzugreifen, die im enthaltenden Bereich definiert sind.
17. Eine öffentliche Methode, die auf private Variablen zugreifen kann, wird als privilegierte Methode bezeichnet. Eine privilegierte Methode kann in einem benutzerdefinierten Typ mithilfe eines Konstruktors oder Prototypmodus implementiert werden, oder sie kann mithilfe eines Modulmodus oder einer Modulerweiterung in einem Singleton-Objekt implementiert werden Modus.

Ich denke du magst

Origin blog.csdn.net/weixin_45732455/article/details/125012310
Empfohlen
Rangfolge