2012-12-13 8 views
5

Jeśli uruchomić następujący kod w google konsoli chrom uzyskać następujące wynikio eval konstruktów oświadczenie i usuwanie

var x = 1; 

alert(delete x); // false 

eval('var y = 2'); 

alert(delete y); // true 

Dlaczego w pierwszym przykładzie zmienna nie zostanie usunięta, a w drugi przykład został usunięty?

+6

Dodatkowe pytanie: dlaczego miałbyś kiedykolwiek tego potrzebować? –

+1

Nie mogę podać żadnych szczegółów technicznych, ale podejrzewam, że jest to związane z zachowaniem JavaScript "[podnosząc] (http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting)". Zasadniczo zmienne zdefiniowane za pomocą 'var foo;' wymagają specjalnej obróbki, ponieważ silnik JS wie, że są one obecne przed uruchomieniem funkcji.Zmienne zadeklarowane przy użyciu 'eval' nie są rozpoznawane i dlatego nie są traktowane jako specjalne. –

+0

Czytasz http://perfectionkills.com/understanding-delete/? – Bergi

Odpowiedz

1

From the Mozilla JS Docs for delete:

delete jest skuteczna tylko na właściwości obiektu. Nie ma on żadnego wpływu na nazwy zmiennych lub funkcji .

Podany przykład jest podobny do Twojego.

x = 42;   // creates the property x on the global object 
var y = 43;  // declares a new variable, y 

delete x;  // returns true (x is a property of the global object and can be deleted) 
delete y;  // returns false (delete doesn't affect variable names) 

Dlaczego więc działa alert(delete y);? Nie mogłem ustalić dokładnej odpowiedzi, ale zasadniczo nie można polegać na zakresie eval.

myślę eval('var y = 2'); nie zostanie zadeklarowana jako zmienna i jest traktowana jako własność, ale nie znaleziono dowodów na to jeszcze inne niż wyniki naszych testów. Zamierzam kontynuować badania, aby sprawdzić, czy znajdę dokładny powód.

Inne artykuły na eval tajemniczości:


EDIT 0

Na podstawie komentarza @Xaviera Holta, spojrzałem na podnoszenie i zakres w odniesieniu do eval. This scope cheatsheet from Mozilla Dev docs miał następujące:

eval może uchwycić zadania, ale nie deklaracje var

eval'd Vars podnosić normalnie, więc evals może uchwycić przypisania podobny się z:

function f() { { 
    let x = "inner"; 
    eval("var x = 'outer'"); 
    print(x); // "outer" } 
} 

Jeśli czytam to poprawnie, moje wcześniejsze założenie było słuszne. eval() nie ocenia deklaracji var przez deklarowanie zmiennej. Musi utworzyć nieruchomość lub być traktowana jako własność, aby zadziałała delete.