Pytanie Wykrywanie niezdefiniowanej właściwości obiektu


Jaki jest najlepszy sposób sprawdzenia, czy właściwość obiektu w kodzie JavaScript jest niezdefiniowana?


2434
2017-08-26 07:25


pochodzenie




Odpowiedzi:


Posługiwać się:

if (typeof something === "undefined") {
    alert("something is undefined");
}

Jeśli zmienna obiektowa posiadająca pewne właściwości, możesz użyć tego samego:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}

Od ECMAScript 5, undefined nie można nadpisać, więc my_obj === undefined też by działało, ale tylko jeśli my_obj istnieje. To może lub nie może być pożądane, ponieważ możesz równie dobrze wykorzystać null jeśli potrzebujesz tego semantycznego (zob Jaka jest różnica między wartością null i niezdefiniowaną w JavaScript?). Jednak dla właściwości obiektu działa niezależnie od tego, czy właściwość istnieje.


2321
2018-01-06 12:27



jeśli coś jest puste, to jest zdefiniowane (jako wartość pusta), ale możesz też odmienić te kontrole. Denerwującym szczegółem powyższego kodu jest to, że nie możesz zdefiniować funkcji, która by to sprawdziła, możesz zdefiniować funkcję ... ale spróbuj jej użyć. - neu-rah
@ neu-rah dlaczego nie możesz napisać funkcji? dlaczego coś takiego nie działałoby? Wydaje się, że działa dla mnie. Czy jest sprawa, której nie rozważam? jsfiddle.net/djH9N/6 - Zack
@Zack Twoje testy dla funkcji isNullorUndefined nie uwzględniają przypadku, w którym wywoływana jest funkcjaNullOrUndefined (f), a f jest niezadeklarowana (tzn. Gdy nie ma deklaracji "var f"). - pnkfelix
Bla, tysiące głosów teraz. To najgorszy możliwy sposób na zrobienie tego. Mam nadzieję, że przechodnie zobaczą ten komentarz i postanowią sprawdzić ... ahem ... inny odpowiedzi. - Ry-♦
Możesz po prostu użyć obj !== undefined teraz. undefined kiedyś zmienne, jak undefined = 1234 co spowodowałoby interesujące wyniki. Ale po Ecmascript 5 nie można już zapisywać, więc możemy użyć prostszej wersji. codereadability.com/how-to-check-for-undefined-in-javascript - Bruno Buccolo


Uważam, że istnieje wiele niepoprawnych odpowiedzi na ten temat. W przeciwieństwie do powszechnego przekonania, "niezdefiniowane" jest nie słowo kluczowe w JavaScript i może w rzeczywistości mieć przypisaną wartość.

Prawidłowy kod

Najsolidniejszym sposobem wykonania tego testu jest:

if (typeof myVar === "undefined")

To zawsze zwróci poprawny wynik, a nawet zajmie się sytuacją, w której myVar nie jest zadeklarowane.

Zdegenerowany kod. NIE UŻYWAJ.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Do tego, myVar === undefined spowoduje błąd w sytuacji, gdy myVar jest niezadeklarowany.


805
2017-08-23 18:03



+1 dla stwierdzenia, że ​​myVar === undefined spowoduje zgłoszenie błędu, jeśli myVar nie został zadeklarowany - Enrique
tak - CYTATY są najwyraźniej niezbędne. zgaduję, że funkcja typeof zwraca ciąg znaków (oczekiwanego formatu) - jsh
Znajduję tutaj pierwsze uzasadnienie braku użycia === undefined oszałamiający. Tak, możesz przypisać do undefined, ale nie ma uzasadnionego powodu, aby to zrobić, i można przewidzieć, że może to spowodować złamanie kodu. W C możesz #define true false, w Pythonie możesz przypisać True i False, ale ludzie nie odczuwają potrzeby zaprojektowania swojego kodu w tych językach w taki sposób, aby chronić się przed możliwością celowego sabotowania własnego środowiska w innym miejscu kodu. Dlaczego możliwość przypisania do undefined nawet warte rozważenia tutaj? - Mark Amery
oprócz komentarzy Marksa, nie rozumiem tego: "myVar === undefined spowoduje błąd w sytuacji, gdy myVar jest niezadeklarowany." - dlaczego jest tak źle? Dlaczego miałabym nie chcesz mieć błąd, jeśli odwołuję się do niezadeklarowanych zmiennych? - eis
W nowoczesnych przeglądarkach (FF4 +, IE9 +, Chrome unknown) nie można już modyfikować undefined. MDN: undefined - Stijn


W JavaScript jest zero i jest niezdefiniowany. Mają różne znaczenia.

  • niezdefiniowany oznacza, że ​​wartość zmiennej nie została zdefiniowana; nie wiadomo, jaka jest wartość.
  • zero oznacza, że ​​wartość zmiennej jest zdefiniowana i ustawiona na wartość null (nie ma wartości).

Marijn Haverbeke podaje w swojej bezpłatnej książce internetowej "Eloquent JavaScript"(podkreślenie moje):

Istnieje również podobna wartość, null, której znaczenie to "ta wartość jest zdefiniowana, ale nie ma wartości". Różnica w znaczeniu między niezdefiniowanym i zerowym jest w większości akademicka i zazwyczaj niezbyt interesująca. W programach praktycznych często konieczne jest sprawdzenie, czy coś "ma wartość". W takich przypadkach można użyć wyrażenia something == undefined, ponieważ, mimo że nie są one dokładnie tej samej wartości, null == undefined da wartość true.

Sądzę więc, że najlepszym sposobem sprawdzenia, czy coś jest nieokreślone, jest:

if (something == undefined)

Mam nadzieję że to pomoże!

Edytować: W odpowiedzi na edycję właściwości obiektu powinny działać w ten sam sposób.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

133
2017-08-26 07:36



if (something == undefined) jest lepiej napisane tak, jakby (coś === undefined) - Sebastian Rittau
Należy podkreślić, że nie jest to całkowicie bezpieczne. undefined to tylko zmienna, która może być ponownie przypisana przez użytkownika: pisanie undefined = 'a'; spowoduje, że twój kod przestanie robić to, co myślisz. Za pomocą typeof jest lepszy i działa również dla zmiennych (nie tylko właściwości), które nie zostały zadeklarowane. - Gabe Moothart
jeśli coś jest niezdefiniowaną zmienną globalną, (coś == undefined) wywołuje błąd javascript. - Morgan Cheng
Problem polega na tym, że jeśli var a = null, a == undefined jest prawdziwe, nawet jeśli a jest na pewno zdefiniowane. - Andrew
Ta interpretacja komentarza "Eloquent Javascript" jest do tyłu. Jeśli naprawdę chcesz po prostu sprawdzić na undefined, sugerowany kod nie będzie działał (wykryje również zdefiniowany warunek, ale żadna wartość nie została jeszcze przypisana [tj. Null]). Wartość pusta. Sugerowany kod "if (something == undefined) ..." sprawdza obie undefined i null (brak zestawu wartości), to jest interpretowane jako "if ((coś jest niezdefiniowane) OR (coś jest pustego)) ..." To, co autor mówi, to często to, co ty naprawdę chcę to sprawdzić obie niezdefiniowany i zerowy. - Chuck Kollars


Pomimo, że jest tu gorąco rekomendowany przez wiele innych odpowiedzi, typeof  jest złym wyborem. Nigdy nie należy go używać do sprawdzania, czy zmienne mają wartość undefined, ponieważ działa jako połączona kontrola wartości undefined i czy istnieje zmienna. W ogromnej większości przypadków wiesz, kiedy istnieje zmienna, i typeof po prostu wprowadzi możliwość cichej awarii, jeśli popełnisz literówkę w nazwie zmiennej lub w ciągu literowym 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

Więc chyba, że ​​robisz detekcję², gdzie nie ma pewności, czy dane nazwisko znajdzie się w zasięgu (jak sprawdzanie typeof module !== 'undefined' jako krok w kodzie specyficznym dla środowiska CommonJS), typeof jest szkodliwym wyborem w przypadku użycia zmiennej, a właściwą opcją jest bezpośrednie porównanie wartości:

var foo = …;

if (foo === undefined) {
    ⋮
}

Oto kilka typowych nieporozumień na ten temat:

  • czytanie "niezainicjowanej" zmiennej (var foo) lub parametr (function bar(foo) { … }, zwany jako bar()) zawiedzie. To po prostu nie jest prawdą - zmienne bez jawnej inicjalizacji i parametry, które nie zostały podane, zawsze stają się wartościami undefinedi zawsze są w zasięgu.

  • że undefined można nadpisać. Jest o wiele więcej. undefined nie jest słowem kluczowym w JavaScript. Zamiast tego jest to właściwość obiektu globalnego o wartości niezdefiniowanej. Jednak od wersji ES5 ta właściwość została tylko czytać i nie można konfigurować. Żadna nowoczesna przeglądarka nie zezwoli na undefined właściwość do zmiany, a od 2017 r. ma to miejsce od dłuższego czasu. Brak trybu ścisłego nie ma wpływu undefinedZachowanie też - po prostu sprawia, że ​​oświadczenia undefined = 5 nie rób nic zamiast rzucania. Ponieważ nie jest to słowo kluczowe, możesz ogłosić zmienne o nazwie undefined, a te zmienne można zmienić, tworząc ten jeden wspólny wzorzec:

    (function (undefined) {
        // …
    })()
    

    jeszcze niebezpieczne niż używanie globalnego undefined. Jeśli musisz być kompatybilny z ES3, wymień undefined z void 0 - nie uciekaj się do typeof. (void zawsze był operatorem jednoargumentowym, który ocenia wartość niezdefiniowaną dla dowolnego operandu).

Ze względu na to, że zmienne nie działają poprawnie, nadszedł czas, aby zająć się rzeczywistym pytaniem: właściwości obiektu. Nie ma powodu, aby kiedykolwiek skorzystać typeof dla właściwości obiektu. Wcześniejszy wyjątek dotyczący wykrywania cech nie ma tutaj zastosowania - typeof ma tylko specjalne zachowanie na zmiennych, a wyrażenia odwołujące się do właściwości obiektu nie są zmiennymi.

To:

if (typeof foo.bar === 'undefined') {
    ⋮
}

jest zawsze dokładnie równoważny do tego3:

if (foo.bar === undefined) {
    ⋮
}

i biorąc pod uwagę powyższe porady, aby nie pomylić czytelników, dlaczego używasz typeof, ponieważ ma sens w użyciu === aby sprawdzić równość, ponieważ może być refaktoryzowana do sprawdzenia wartości zmiennej później, a ponieważ po prostu wygląda lepiej, powinieneś zawsze używać === undefined³ również tutaj.

Coś innego do rozważenia, jeśli chodzi o właściwości obiektów, jest to, czy naprawdę chcesz sprawdzić undefined w ogóle. Dana nazwa właściwości może być nieobecna na obiekcie (tworząc wartość undefined przy odczycie), obecny na samym obiekcie z wartością undefined, obecne na prototypie obiektu z wartością undefinedlub obecne na którymkolwiek z osóbundefined wartość. 'key' in obj powie ci, czy klucz jest gdziekolwiek w łańcuchu prototypów obiektu, i Object.prototype.hasOwnProperty.call(obj, 'key') powie ci, czy jest to bezpośrednio na obiekcie. Nie będę jednak szczegółowo omawiał tej odpowiedzi na temat prototypów i używania obiektów w postaci map z ciągami znaków, ponieważ ma ona głównie na celu przeciwdziałanie złym radom w innych odpowiedziach, niezależnie od możliwych interpretacji pierwotnego pytania. Czytaj dalej prototypy obiektów na MDN więcej!

¹ nietypowy wybór przykładowej nazwy zmiennej? to jest prawdziwy martwy kod z rozszerzenia NoScript dla Firefoksa.
² nie zakładaj, że nie wie jednak, co jest w zasięgu. podatna luka spowodowana nadużyciem zakresu dynamicznego: Project Zero 1225
³ po raz kolejny zakładając środowisko ES5 + i inne undefined odnosi się do undefined własność obiektu globalnego. zastąpić void 0 Inaczej.


132
2018-02-26 21:17



@BenjaminGruenbaum Prawdziwe, ale całkowicie mylące. Każdy inny niż domyślny kontekst może zdefiniować własny undefined, ukrywając domyślny. Który w większości praktycznych celów ma taki sam efekt jak nadpisanie go. - blgt
@blgt To paranoiczne i nieistotne dla niczego praktycznego. Każdy kontekst może przesłonić console.log, przedefiniować metody prototypowe Array, a nawet przesłonić funkcję Function.prototype.call` i zmieniać za każdym razem, gdy wywołasz funkcję w JavaScript. Ochrona przed tym jest bardzo paranoidalna i raczej głupia. Tak jak powiedziałem (i minitech), możesz użyć void 0 porównać z niezdefiniowanym, ale znowu - to głupie i przesadne. - Benjamin Gruenbaum
Chciałbym mieć więcej niż jeden upominek. To jest najbardziej poprawna odpowiedź. Naprawdę chcę przestać widzieć typeof something === "undefined")  W kodzie. - Simon Baumgardt-Wellander
@BenjaminGruenbaum Dla leniwych programistów, void 0 jest (na razie) krócej i bezpieczniej! To wygrana w mojej książce. - wizzwizz4


Co to znaczy: "niezdefiniowana właściwość obiektu"?

Właściwie może to oznaczać dwie zupełnie różne rzeczy! Po pierwsze, może to oznaczać właściwość, która nigdy nie została zdefiniowana w obiekcie, a po drugie, może oznaczać właściwość, która ma niezdefiniowaną wartość. Spójrzmy na ten kod:

var o = { a: undefined }

Jest o.a niezdefiniowany? Tak! Jego wartość jest niezdefiniowana. Jest o.b niezdefiniowany? Pewnie! W ogóle nie ma własności "b"! OK, zobacz teraz, jak różne podejścia zachowują się w obu sytuacjach:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

Możemy to wyraźnie zobaczyć typeof obj.prop == 'undefined' i obj.prop === undefined są równoważne i nie rozróżniają tych różnych sytuacji. I 'prop' in obj potrafi wykryć sytuację, gdy właściwość nie została w ogóle zdefiniowana i nie zwraca uwagi na wartość właściwości, która może być nieokreślona.

Więc co robić?

1) Chcesz wiedzieć, czy właściwość jest niezdefiniowana przez pierwsze lub drugie znaczenie (najbardziej typowa sytuacja).

obj.prop === undefined // IMHO, see "final fight" below

2) Chcesz wiedzieć, czy obiekt ma jakąś własność i nie przejmuje się jego wartością.

'prop' in obj

Uwagi:

  • Nie możesz sprawdzić obiektu i jego własności w tym samym czasie. Na przykład to x.a === undefined albo to typeof x.a == 'undefined' podnosi ReferenceError: x is not defined jeśli x nie jest zdefiniowane.
  • Zmienna undefined jest zmienną globalną (tak naprawdę jest window.undefined w przeglądarkach). Jest wspierany od wydania ECMAScript 1st Edition i od wersji ECMAScript 5 tylko czytać. Więc w nowoczesnych przeglądarkach tak być nie może ponownie zdefiniowane jako prawdziwe jak wielu autorów uwielbia nas straszyć, ale jest to nadal prawdziwe w przypadku starszych przeglądarek.

Finałowa walka: obj.prop === undefined vs typeof obj.prop == 'undefined'

Plusy obj.prop === undefined:

  • Jest nieco krótszy i wygląda nieco ładniej
  • Silnik JavaScript da ci błąd, jeśli masz błąd w pisowni undefined

Minusy obj.prop === undefined:

  • undefined mogą być przesłonięte w starszych przeglądarkach

Plusy typeof obj.prop == 'undefined':

  • Jest naprawdę uniwersalny! Działa w nowych i starych przeglądarkach.

Minusy typeof obj.prop == 'undefined':

  • 'undefned' (błędnie napisany) tutaj jest tylko stała łańcuchowa, więc silnik JavaScript nie może ci pomóc, jeśli masz błąd w pisowni, tak jak właśnie.

Aktualizacja (dla JavaScript po stronie serwera):

Node.js obsługuje zmienną globalną undefined tak jak global.undefined (może być również używany bez prefiksu "globalnego"). Nie wiem o innych implementacjach JavaScript po stronie serwera.


101
2017-08-08 20:28



@Bergi dziękuję za komentarz. Poprawiłem moją odpowiedź. W mojej obronie mogę powiedzieć, że obecnie (stan na 10.10.18) oficjalna dokumentacja Node.js nic nie mówi undefined jako członek global. Również nie console.log(global); ani for (var key in global) { ... } nie wyświetla się niezdefiniowany jako członek światowy. Ale sprawdź jak 'undefined' in global pokaż odwrotnie. - Konstantin Smolyanin
Od tego czasu nie potrzebowała dodatkowej dokumentacji jest w specyfikacji EcmaScript, który również to mówi [[Enumerable]] to fałsz :-) - Bergi
Jeżeli chodzi o Minuses of typeof obj.prop == 'undefined', można tego uniknąć, pisząc jako typeof obj.prop == typeof undefined. Daje to również bardzo ładną symetrię. - hlovdal
@hlovdal: To zupełnie bezsensowne obj.prop === undefined. - Ry-♦
Kiedy jesteśmy wierni nagłówkowi pytania "Wykrywanie niezdefiniowana właściwość ", nie odpowiadając na pytanie (różne i dużo łatwiejsze) w pierwszym zdaniu ("sprawdź czy niezdefiniowane ..."), odpowiadasz if ('foo' in o) ... twoja odpowiedź jest naprawdę pierwszą poprawną odpowiedzią tutaj. Niemal wszyscy po prostu odpowiadają na to zdanie. - Frank Nocke


Problem sprowadza się do trzech przypadków:

  1. Obiekt ma właściwość, a jego wartość nie jest undefined.
  2. Obiekt ma właściwość i jego wartość jest undefined.
  3. Obiekt nie ma właściwości.

To mówi nam coś, co uważam za ważne:

Istnieje różnica między niezdefiniowanym elementem a zdefiniowanym elementem o nieokreślonej wartości.

Ale nieszczęśliwie typeof obj.foo nie mówi nam, które z trzech spraw mamy. Jednak możemy to połączyć z "foo" in objrozróżniać przypadki.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

Warto zauważyć, że te testy są takie same null również wpisy

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Twierdzę, że w niektórych przypadkach bardziej sensowne (i bardziej przejrzyste) jest sprawdzenie, czy nieruchomość tam jest, niż sprawdzenie, czy jest ona nieokreślona, ​​a jedynym przypadkiem, w którym ta kontrola będzie inna, jest przypadek 2, rzadki przypadek faktyczny wpis w obiekcie o nieokreślonej wartości.

Na przykład: Właśnie refactorowałem wiązkę kodu, która zawierała kilka sprawdzeń, czy obiekt ma daną właściwość.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Które było wyraźniejsze, gdy napisane bez sprawdzenia dla nieokreślonego.

if( "x" in blob ) { fn(blob.x); }

Ale jak już wspomniano, nie są one dokładnie takie same (ale są więcej niż wystarczająco dobre dla moich potrzeb).


59
2018-06-08 04:04



Cześć Michał. Świetna sugestia i myślę, że to czyni sprawy czystszymi. Jedną z nich, którą znalazłem, jest użycie! operator z "in". Musisz powiedzieć if (!("x" in blob)) {} z nawiasami wokół, ponieważ! operator ma pierwszeństwo przed "w". Mam nadzieję, że pomaga komuś. - Simon East
Przepraszam, Michael, ale jest to niepoprawne, a przynajmniej mylące, w świetle pierwotnego pytania. "in" nie jest wystarczającym sposobem sprawdzenia, czy właściwość obiektu ma typ niezdefiniowany. Aby sprawdzić, proszę zobacz ten skrzypce: jsfiddle.net/CsLKJ/4 - Tex
Te dwie części kodu robią coś innego! Zastanów się i podaruj przedmiot przez a = {b: undefined}; następnie typeof a.b === typeof a.c === 'undefined' ale 'b' in a i !('c' in a). - mgol
+1. PO nie wyjaśnia, czy właściwość istnieje i ma taką wartość niezdefiniowanylub czy sama własność jest niezdefiniowana (tj. nie istnieje). - RobG
Sugerowałbym zmianę punktu (2.) w twoim pierwszym stole na { x : undefined } lub przynajmniej dodać go jako kolejną alternatywę do (2.) w tabeli - musiałem przez chwilę pomyśleć, aby zdać sobie sprawę, że punkt (2) ocenia undefined (chociaż wspomniałeś o tym później). - mucaho


if ( typeof( something ) == "undefined") 

To działało dla mnie, podczas gdy inni nie.


38
2017-07-27 16:03



parens są niepotrzebne, ponieważ typeof jest operatorem - aehlke
Ale sprawiają, że jest bardziej przejrzyste, co jest sprawdzane. W przeciwnym razie może być odczytany jako typeof (something == "undefined"). - Abhi Beckert
Jeśli potrzebujesz nawiasów, powinieneś nauczyć się pierwszeństwa operatorów w JS: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - Ian
Nawiasy są użyteczne właśnie dlatego, że NIE musisz uczyć się pierwszeństwa operatorów w JS, ani nie musisz spekulować, czy przyszli programiści konserwacji będą musieli nauczyć się pierwszeństwa operatora w JS. - DaveWalley
Nawias są użyteczne do wyjaśnienia rzeczy. Ale w tym przypadku po prostu sprawiają, że operator wygląda jak funkcja. Bez wątpienia to wyjaśnia intencje programisty. Ale jeśli nie masz pewności co do pierwszeństwa operatora, powinieneś raczej napisać to jako (typeof something) === "undefined". - Robert


Nie jestem pewien, skąd pochodzi używanie === z typeof pochodzę i jako konwencja widzę, że jest on używany w wielu bibliotekach, ale operator typeof zwraca literał łańcuchowy i wiemy o tym z góry, więc dlaczego chcesz go również wpisać?

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient

33
2017-09-22 14:20



Świetny punkt Eric. Czy istnieje również skuteczność działania polegająca na sprawdzaniu typu? - Simon East
@Simon: wręcz przeciwnie - można by oczekiwać niewielkiego uderzenia wydajnościowego w wyniku uniknięcia przymusu w przypadku "===". Szybki i brudny test wykazał, że "===" jest o 5% szybsze niż "==" pod FF5.0.1 - Antony Hatchkins
Bardziej dokładny test wykazał, że pod FF, IE i Chrome "==" jest mniej więcej szybszy niż "===" (5-10%), a Opera nie robi żadnej różnicy: jsperf.com/triple-equals-vs-twice-equals/6 - Antony Hatchkins
Za pomocą == wciąż wymaga przynajmniej kontrola typu - tłumacz nie może porównać dwóch argumentów bez znajomości ich typu. - Alnitak
== jest o jeden znak mniejszy niż === :) - svidgen


Crossposting my odpowiedź z pokrewnego pytania Jak sprawdzić "niezdefiniowany" w JavaScript?

Specyficzne dla tego pytania, zobacz przypadki testowe z someObject.<whatever>.


Niektóre scenariusze ilustrujące wyniki różnych odpowiedzi: http://jsfiddle.net/drzaus/UVjM4/

(Należy pamiętać, że użycie var dla in testy robią różnicę w opakowaniu z zakresem)

Kod referencyjny:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

I wyniki:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined

19
2018-01-13 17:43





Jeśli zrobisz

if (myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

zawiedzie, gdy zmienna myvar nie istnieje, ponieważ myvar nie jest zdefiniowany, więc skrypt jest zepsuty, a test nie działa.

Ponieważ obiekt okna ma zakres globalny (obiekt domyślny) poza funkcją, deklaracja zostanie "dołączona" do obiektu okna.

Na przykład:

var myvar = 'test';

Zmienna globalna myvar jest taki sam jak window.myvar lub okno ['myvar']

Aby uniknąć błędów podczas testowania, gdy istnieje zmienna globalna, lepiej użyj:

if(window.myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

Pytanie, czy zmienna rzeczywiście istnieje, nie ma znaczenia, jej wartość jest niepoprawna. W przeciwnym razie niemądrze jest zainicjować zmienne o niezdefiniowanej wartości i lepiej użyć wartości false do zainicjowania. Kiedy wiesz, że wszystkie deklarowane zmienne są inicjowane z wartością false, możesz po prostu sprawdzić jego typ lub polegać na nim !window.myvar aby sprawdzić, czy ma prawidłową / prawidłową wartość. Więc nawet wtedy, gdy zmienna nie jest zdefiniowana, wtedy !window.myvar jest taki sam dla myvar = undefined lub myvar = false lub myvar = 0.

Kiedy oczekujesz określonego typu, przetestuj typ zmiennej. Aby przyspieszyć testowanie stanu, lepiej wykonaj:

if( !window.myvar || typeof window.myvar != 'string' )
{
    alert('var does not exists or is not type of string');
}

Kiedy pierwszy i prosty warunek jest prawdziwy, interpreter pomija następne testy.

Zawsze lepiej jest użyć instancji / obiektu zmiennej, aby sprawdzić, czy otrzymała poprawną wartość. Jest bardziej stabilny i jest lepszym sposobem programowania.

(y)


14
2017-08-12 14:40





Nie widziałem (mam nadzieję, że mi tego nie brakowało), kto sprawdzał obiekt przed nieruchomością. Jest to najkrótsza i najskuteczniejsza (choć niekoniecznie najbardziej przejrzysta):

if (obj && obj.prop) {
  // Do something;
}

Jeśli obj lub obj.prop jest niezdefiniowany, null lub "falsy", instrukcja if nie wykona bloku kodu. To jest zazwyczaj pożądane zachowanie w większości instrukcji blokowych kodu (w JavaScript).


13
2017-09-25 18:41



Jeśli chcesz wiedzieć, dlaczego to działa: JavaScript: operatory logiczne i prawda / falsy - mb21
jeśli chcesz przypisać właściwość do zmiennej, jeśli jest ona zdefiniowana, nie null i nie falsey, w przeciwnym razie użyj jakiejś wartości domyślnej, możesz użyć: var x = obj && obj.prop || 'default'; - Stijn de Witt
Uważam, że pytanie dotyczy bezpośredniego sprawdzenia nieokreślonego. Twój warunek sprawdza wszystkie fałszywe wartości JS. - NikoKyriakid