Im folgenden Beispiel versuche ich, eine Ausgabe zu erhalten, die dem Typ einer Funktion eine Zahl hinzufügt, aber die Ausgabe scheint anders zu sein.

<html>
<head></head>
<body>

<script>

var k = 1;
if (1) {
   eval(function foo(){});
   k += typeof foo; 
}
console.log(k); 

</script>

</body>
</html>

Erwartete Ausgabe:

1function

Tatsächliche Ausgabe:

1undefined

Kann jemand erklären, warum die Ausgabe anders ist als erwartet?

Hinweis: Die Art der Bewertung (function () {}) gibt das Ergebnis der Funktion an.

enter image description here

0
Deadpool 18 Apr. 2018 im 16:23

4 Antworten

Beste Antwort

Sie benötigen das eval für dieses Snippet nicht wirklich. typeof (function foo(){}) vs. typeof foo hat das gleiche Ergebnis. Sie brauchen eval nicht, da eval(function foo(){}) und (function foo(){}) identisch sind, da das Argument keine Zeichenfolge ist. Wenn Sie eval verwenden möchten, verwenden Sie stattdessen Zeichenfolgen:

var x = function foo(){};

console.log(eval(x) === x); // true, because they’re identical

eval("function foo(){}");
// or
eval("var foo = function foo(){}");

console.log(foo); // function foo, because one of the above `eval`s declared it

function foo(){} ist hier ein Funktionsausdruck. Ihre Namen sind nur in sich selbst zugänglich, nicht außerhalb. Eine Funktionsdeklaration oder ein zugewiesener Funktionsausdruck wäre außerhalb zugänglich.

(function foo(){}); // (…) forces expression context. `foo` is not defined outside of it.

console.log(foo); // ReferenceError
var foo = function foo(){}; // Right-hand side is an expression, thus this is a function expression, but its result is assigned to a variable.

console.log(foo); // function foo
var bar = function foo(){}; // Same thing, but with a different variable.

console.log(bar); // function foo
console.log(foo); // ReferenceError, since the name `foo` still is not visible outside.
function foo(){} // Statement context, thus this is a function declaration

console.log(foo); // function foo

(function foo(){ console.log(foo); }) wäre also in Ordnung, wenn die Funktion aufgerufen würde, nicht unbedingt mit demselben Namen.

Schließlich gibt typeof "undefined" für nicht deklarierte Variablen zurück.

1
user4642212 18 Apr. 2018 im 13:56

Soweit ich weiß, haben Sie dieser Funktion einen Namen gegeben, aber Sie haben sie nicht an eine Variable "gebunden", sodass die Funktion vorhanden ist, aber es gibt keinen "Zeiger", der auf diese Funktion zeigt. typeof benötigt einen "Zeiger" auf etwas, das ausgewertet werden soll, aber Sie haben niemanden deklariert, sondern dieser Funktion nur einen Namen gegeben. Dies ist für Debugging-Zwecke nur dann nützlich, wenn Sie die Funktion nicht direkt ausführen möchten.

Es ist in Ordnung, das Objekt auch direkt zu übergeben:

var k = 1;
if (1) {
   k += typeof function foo(){}; //1function
}
console.log(k);
-1
amedina 18 Apr. 2018 im 13:44

Typeof foo gibt undefiniert zurück, da es in diesem Bereich nicht definiert ist

K + = undefined wird in einen String umgewandelt und führt zu:

1Funktion

-1
b3nc1 18 Apr. 2018 im 13:30

Eval () erwartet einen String als Argument. Sie müssen also die Funktion foo () in Anführungszeichen setzen.

var k = 1;

if (1) {
  eval('function foo(){}');
  k += typeof foo; 
}

console.log(k);

Dokumentation: https://developer.mozilla.org/en- US / docs / Web / JavaScript / Reference / Global_Objects / eval

-1
William Antony 18 Apr. 2018 im 13:32