Heim  >  Artikel  >  Web-Frontend  >  Codedetails von Funktionsaufrufen in JavaScript

Codedetails von Funktionsaufrufen in JavaScript

黄舟
黄舟Original
2017-03-23 14:26:101390Durchsuche

Viele Menschen sind beim Erlernen von JavaScript möglicherweise auf Verwirrung über die Bereitstellungsmethode Funktionsparameter gestoßen. Im Sinne einer gründlichen Untersuchung werde ich ein Tutorial mit Ihnen teilen über JavaScript. Wissen über Funktionsaufrufe, interessierte Freunde, lasst uns gemeinsam lernen

Definition

Viele Menschen sind beim Lernen möglicherweise auf Funktionsparameter gestoßen Javascript Ich bin verwirrt über die Übertragungsmethode und möchte im Sinne einer eingehenden Analyse einige Antworten im Quellcode finden. Bevor ich dies tue, muss ich jedoch zunächst einige Konzepte klären. Verzichten Sie auf die inhärenten Namen von Wertübergabe, Referenzübergabe usw. und kehren Sie zum Englischen zurück:

Call by Reference && Call by Value && Call by Sharing

Sie verstehen wir unter Referenzübergabe und Wertübergabe in C++. Die dritte ist verwirrender. Die offizielle Erklärung lautet: erhält die Kopie des Verweises auf das Objekt . Lassen Sie es mich in Laienbegriffen erklären:

Objekt kann als Sammlung von Schlüssel verstanden werden. Das Objekt bezieht sich auf die Daten, auf die der Schlüssel zeigt (ich werde nicht näher darauf eingehen, ob es sich um einen Zeiger handelt Implementierung oder eine C++-Referenzimplementierung). Was die Funktion erhält, ist eine Kopie einer -Variable . Die Variable enthält einen Verweis auf das Objekt und wird als Wert übergeben.

Dann ist es offensichtlich, dass der Typparameter Objekt, den wir bei der Übergabe von Funktionsparametern erhalten, tatsächlich eine Kopie des tatsächlichen Parameters ist, sodass es nicht möglich ist, den Zeiger des Typparameters direkt zu ändern ; weil das Objekt selbst Die Schlüssel sind alle Referenzen, daher ist es möglich, den Zeiger des Schlüssels zu ändern.

Beweis

Ein paar einfache Codeteile können es beweisen

Code 1: Die Funktion kann die angezeigten Daten ändern per Taste

let func = obj => { obj.name = 'Dosk' };
let obj = {name : 'Alxw'};
console.log(obj); //{ name: 'Alxw' }
func(obj)
console.log(obj); //{ name: 'Dosk' }

Code 2: Die Funktion kann obj nicht ändern

let func = obj => { obj = {} };
let obj = {name : 'Alxw'};
console.log(obj); //{ name: 'Alxw' }
func(obj)
console.log(obj); //{ name: 'Alxw' }

Code 3: Das interne obj und das externe === Ergebnis sind gleich

let def = {name : 'Alxw'};
let func = obj => { console.log(obj === def) };
func(def); //true

Also der dritte Teil des Codes. Da obj eine Kopie von def ist, warum kann die Operation === immer noch wahr sein? Bedeutet das nicht, dass die Operation === die Adresse im Speicher für das Objekt vergleicht? Wenn es sich um eine Kopie handelt, sollte sie falsch sein?

Kehren wir also zum Quellcode von Google V8 zurück, um uns das anzusehen.

Tief in Google V8

Werfen wir einen Blick auf den streng gleichen Operationscode-Teil im Quellcode:

bool Object::StrictEquals(Object* that) {
 if (this->IsNumber()) {
  if (!that->IsNumber()) return false;
  return NumberEquals(this, that);
 } else if (this->IsString()) {
  if (!that->IsString()) return false;
  return String::cast(this)->Equals(String::cast(that));
 } else if (this->IsSimd128Value()) {
  if (!that->IsSimd128Value()) return false;
  return Simd128Value::cast(this)->Equals(Simd128Value::cast(that));
 }
 return this == that;
}

Es sieht so aus, als ob dies theoretisch der letzte Fall sein sollte. Wenn def und obj unterschiedliche Objekte sind, sollte dadurch nicht false zurückgegeben werden. Eigentlich nein, eines wird ignoriert: Wenn ein Objekt intern instanziiert wird, ist Google V8 selbst eine dynamische Instanziierung, und wir wissen, dass in kompilierten Sprachen die dynamische Instanziierung nur im Heap-Speicher durchgeführt werden kann, dh nur Zeiger verwendet werden. Der Beweis dieser Schlussfolgerung beinhaltet die Implementierung von Local, Handle und anderen Klassen. Es gibt einen einfachen Weg, dies zu beweisen 🎜> Durchsuchen Sie den -Quellcode. Alle Stellen, an denen aufgerufen werden, werden direkt übergeben, ohne dass die Adressoperation ausgeführt wird. Object::StrictEquals

Einige Leute fragen sich jedoch möglicherweise, dass es theoretisch möglich ist, Object zu ändern, da die als Wert übergebene Variable einen Verweis auf Object enthält. Warum kann der dritte Teil des Codes nicht geändert werden?

Der Grund ist sehr einfach, denn unsere sogenannten Operationen auf der logischen Ebene der Javascript-Sprache rufen lediglich die Instanzmethode von Google V8 auf und es ist unmöglich, bis zu diesem Punkt zu arbeiten (natürlich ein potenzieller Fehler). wird nicht gezählt -. -)

Neudefinition

Ich denke, ich kann den Anruf noch einmal erklären, indem ich ihn hier teile:

Es wird zwar als Wert übergeben, aber der Inhalt enthält den Zeiger des Objekts, und dieser Zeiger kann nicht geändert werden. Er wird von mehreren Variablen gemeinsam genutzt.

Noch ein einfacher Beweis

Komm, schau dir den Quellcode an

V8_DEPRECATE_SOON("Use maybe version",
         Local<Value> Call(Local<Value> recv, int argc,
                  Local<Value> argv[]));
V8_WARN_UNUSED_RESULT MaybeLocal<Value> Call(Local<Context> context,
                       Local<Value> recv, int argc,
                       Local<Value> argv[]);
Das Obige steht kurz bevor aufgegeben Die

Schnittstelle wird verwendet. Es kommt vor, dass der Versionscode, den ich gesehen habe, einen Großteil dieses Codes enthält, der bald veraltet ist. Der Fokus liegt auf der zweiten Schnittstelle, die die einzige aufrufende Schnittstelle der Funktion ist. Das im Inneren ruft schließlich die Bitkopie von C++ auf, sodass leicht nachgewiesen werden kann, dass es als Wert übergeben wird. Locale014ece7d12df732a4e3dd019e3e87f3

könnte der entscheidende Punkt sein

Vergessen Sie nicht, dass die von uns definierten Variablen alle die Form

haben, also sie Objekte werden von Objekten gemeinsam genutzt. Was wir in Javascript Variablen nennen, bezieht sich nicht direkt auf Instanzen von Objekten!!!Handlea87fdacec66f0909fc0757c19f2d2b1d

Das Letzte

Kurz gesagt, es kann schwierig sein, es zu verstehen oder sogar Fehler zu enthalten, aber es ist wichtig, die Merkmale auf der Ebene der Javascript-Sprache bestimmen zu können.

Das Obige ist der Funktionsaufruf in Javascript, den Ihnen der Herausgeber vorgestellt hat. Ich hoffe, er wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Herausgeber wird Ihnen rechtzeitig antworten . Ich möchte mich auch bei Ihnen allen für Ihre Unterstützung der Script House-Website bedanken!

Das obige ist der detaillierte Inhalt vonCodedetails von Funktionsaufrufen in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn