2016-04-16 2 views
3

Ich verstehe das Konzept der Variablen und Funktionsdeklaration in JavaScript am oberen Rand des umschließenden Bereichs gehisst. Aber wenn ich eine benannte Callback-Funktion habe, wird sie nicht gehisst. Ich verstehe nicht, warum das so ist. Ich habe den Code in dem unten stehenden Link das SzenarioWarum werden Callback-Funktionen nicht in JavaScript gehostet?

Beispiel erläutern:

function enclosingScope() { 
    var b; 

    function inner (def) { 
    def(); 
    } 
    var a = 2; 
} 

// After hoisting due to compilation, the above changes to 
function enclosingScope() { 
    // Function declarations are hoisted before variables 
    function inner (def) { 
    def(); 
    } 

    var b, a; 
    a = 2 
} 

// But if I have a named callback, will that be hoisted? 
function enclosingScope() { 
    function inner (def) { 
    def(); 
    } 

    var b, a; 
    a = 2 

    inner(function cb() { 
    console.log('Test callback hoisting') 
    }) 
} 
+1

F: Was ist passiert, als Sie es versucht haben? F: Warum sogar * fragen *, ohne es einfach selbst auszuprobieren? Du hast * den * Code - was hast du gefunden ??? – paulsm4

+0

Ich habe die Frage bearbeitet.Vielleicht können Sie jetzt einen Blick darauf werfen und helfen –

+2

Wenn Sie über Ihre cb() - Funktion sprechen, ist es eine benannte Funktion Ausdruck und Sie übergeben einen Verweis auf es auf die innere() Funktion. Funktionsausdrücke werden nicht gehißt, und der Name cb kann nur innerhalb dieser Funktion verwendet werden - er erstellt keine Variable cb innerhalb des Bereichs, also gibt es nichts zu hissen, und tatsächlich bezieht sich dein Code nie irgendwo anders auf cb . – nnnnnn

Antwort

3

Das fragliche Verhalten ist nicht auf dem Namen Callbacks beschränkt. So funktioniert jeder benannte Funktionsausdruck. Beachten Sie Folgendes:

function foo() { 
    (function baz() { }); 
    console.log(typeof baz); 
} 

> foo() 
< undefined 

baz außerhalb seines Körpers nicht zugänglich ist. Das ist ein anderes Thema als das Heben.

1

finde ich die Antwort gegeben zu kurz ist, hier so ist eine kanonische Erklärung:

Javascript unterscheidet zwischen Funktionsdeklarationen

function f() {} 

und Funktionsausdrücken

var f = function() {} // anynomous function or lambda 
var g = function h() {} // named function expression 

Funktionsdeklarationen Aussagen, während Funktion Ausdrücke sind ..., rate was? Yay, Ausdrücke. Bitte beachten Sie, dass der Name eines benannten Funktionsausdrucks (h im angegebenen Beispiel) nur innerhalb des Funktionskörpers (von g im gegebenen Beispiel) erreichbar ist.

Wenn Sie eine Funktionsdeklaration in Klammern verschachteln, wird sie automatisch in einen Ausdruck konvertiert. Das bedeutet, dass Ihr function cb() {...} nur ein benannter Funktionsausdruck ist. Sie weisen es jedoch keiner Variablen zu, sondern übergeben es als Argument an inner.

Beim Heben im Zusammenhang mit Funktionsausdrücken wird nur die Deklaration der zugewiesenen Variablen gehisst. Dies ist nicht der Fall mit Funktionsdeklarationen:

console.log(f); // function f 
console.log(g); // exists, but undefined 
console.log(h); // reference error 

function f() {} 
var g = function h() {} 

Da cb in Ihrem Beispiel nicht zu einer Variablen zugewiesen wird, kann es keine Hebe sein.

Diese beiden Linien sind daher gleichwertig in Bezug auf Hebe:

inner(function cb(){}); 
(function cb(){}); 

Bonus:const/let

Wenn Sie versuchen, eine Funktion Ausdruck mit const oder let jedoch erklärt zu nennen, lexikalisch vor seiner Erklärung, ein Referenzfehler ausgelöst:

console.log(g); // reference error 
const g = function h() {} 

g wird auch gehisst. Aber um Sie vor unerwarteten undefined s zu schützen. Der Interpreter gibt einen Fehler aus. Ich denke, das ist klug.

Verwandte Themen