2013-06-23 22 views
8

Pochodzę z tła innego niż javascript, staram się owijać głowę "niezdefiniowanym". napisałem funkcję „isUndefined” w następujący sposób:Zrozumienie funkcji i niezdefiniowana

function isUndefined(value) { 
    return (typeof value === 'undefined'); 
} 

gdybym wpisać moje źródło to (gdzie zmienna „boo” nie istnieje), otrzymuję oczekiwanego rezultatu „Zmienna niezdefiniowana”.

if (typeof boo === 'undefined') { 
    console.log('undefined variable'); 
} 

gdybym wpisać następujący: console.log (isUndefined(undefined));

uzyskać oczekiwany rezultat 'true'

Gdybym wpisać: console.log(isUndefined(boo));

uzyskać:

Reference Error: boo is not defined.

Spodziewałem się, że otrzymam "true" - więc mój Pytanie brzmi: dlaczego pierwsza "bezpośrednia" kontrola dla niezdefiniowanych zwraca oczekiwany wynik, ale test funkcji() na to nie działa?

+1

Jesteś prawo być zaskoczony przez to. –

+0

z jakiego tła pochodzisz? – galchen

+1

http://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/ – goat

Odpowiedz

7

Jest różnica między istniejącej zmiennej, która akurat zawierać wartość undefined, a zmienną, która nie istnieje w ogóle. Jeśli nazwa zmiennej nie istnieje, błędem jest próba jej odniesienia.

Operator typeof jest szczególnym przypadkiem: akceptuje nazwę, nawet jeśli nie ma takiej zmiennej o tej nazwie. Ale tylko wtedy, gdy nazwa jest rzeczywiście używana z operatorem typeof.

W swoim przykładzie funkcji używasz nazwy, która nie istnieje, i nie ma operatora w miejscu, w którym używana jest nazwa. Tutaj pojawia się błąd. Nie ma znaczenia, że ​​przekazujesz nazwę do funkcji, która będzie używać typeof; ta funkcja nigdy nie zostanie wywołana, ponieważ błąd już się zdarzył.

Twoja funkcja będzie działać zgodnie z oczekiwaniami, jeśli nadasz jej istniejącą nazwę. Wtedy byłoby powiedzieć, czy ta zmienna ma wartość undefined lub nie:

var boo; // now boo exists but has the undefined value 
console.log(isUndefined(boo)); // will log 'true' 

Jeśli sprawdzali zmienną globalną, to działa, jeśli powiedział window.boo zamiast tylko boo.Jest tak dlatego, że nie jest błędem odwoływanie się do nieistniejącej własności obiektu; to po prostu daje wartość undefined kiedy to zrobić:

// logs 'true' if there is no global 'boo' 
console.log(isUndefined(window.boo)); 

To nie będzie działać, jeśli chcesz sprawdzić, czy zmienna lokalna istnieje, choć, ponieważ nie będzie własnością window obiekt.

3

Ujmę to tak:

var a = 5; 
function foo(v){ 
    v += 5; 
    console.log(v); 
} 

foo(a); 
console.log(a); // will give you 5, not 10 

z tego samego powodu - podczas rozmowy

isUndefined(boo) 

zmiennej boo nie zostanie wysłany, wartość boo jest wysyłany. Ponieważ boo nie jest zdefiniowane podczas połączenia, pojawia się błąd, gdy próbujesz osiągnąć jego wartość.

Warto wspomnieć, że typeof nie jest funkcją, to operator

2

Zwykle zachowanie w JavaScript w celu uzyskania dostępu do zmiennej, która nie istnieje, powoduje odrzucenie odwołania ReferenceError. Operator typeof jest tutaj wyjątkiem, ponieważ jest specjalnie zakodowany, aby nie dawać takiego błędu, jeśli przekażesz mu zmienną, która nie istnieje.

http://es5.github.io/#x11.4.3

11.4.3 The typeof Operator # Ⓣ

The production UnaryExpression : typeof UnaryExpression is evaluated as follows:

Let val be the result of evaluating UnaryExpression. 

If Type(val) is Reference, then 

    If IsUnresolvableReference(val) is true, return "undefined". 

    Let val be GetValue(val). 

Aby uniknąć ReferenceError można zadeklarować boo wcześniej bez przypisywania coś do niego:

var boo; 
console.log(isUndefined(boo)); 
console.log(typeof boo == 'undefined') 
Powiązane problemy