Jaki jest najlepszy sposób sprawdzenia, czy właściwość obiektu w JavaScript jest undefined
?
Jaki jest najlepszy sposób sprawdzenia, czy właściwość obiektu w JavaScript jest undefined
?
Odpowiedzi:
Typowym sposobem sprawdzenia, czy wartość właściwości jest wartością specjalną undefined
, jest:
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
Aby sprawdzić, czy obiekt tak naprawdę nie ma takiej właściwości, dlatego undefined
domyślnie wróci , gdy spróbujesz uzyskać do niego dostęp:
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
Aby sprawdzić, czy wartość związana z identyfikatorem jest wartość specjalny undefined
, lub jeśli identyfikator nie został uznany. Uwaga: ta metoda jest jedynym sposobem odwoływania się do niezadeklarowanego (uwaga: różniącego się od posiadania wartości undefined
) identyfikatora bez wczesnego błędu:
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
W wersjach JavaScript wcześniejszych niż ECMAScript 5 właściwość o nazwie „undefined” w obiekcie globalnym była zapisywalna, a zatem proste sprawdzenie foo === undefined
może zachowywać się nieoczekiwanie, jeśli zostanie przypadkowo przedefiniowane. W nowoczesnym JavaScript właściwość jest tylko do odczytu.
Jednak we współczesnym JavaScript JavaScript słowo „niezdefiniowany” nie jest słowem kluczowym, dlatego zmienne w funkcjach można nazwać „niezdefiniowanymi” i zasłaniać globalną właściwość.
Jeśli martwi Cię ten (mało prawdopodobny) przypadek krawędzi, możesz użyć operatora pustki, aby uzyskać undefined
samą wartość specjalną :
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
obj !== undefined
teraz. undefined
Kiedyś można go było modyfikować, tak undefined = 1234
jak w przypadku interesujących wyników. 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
Uważam, że istnieje wiele niepoprawnych odpowiedzi na ten temat. Wbrew powszechnemu przekonaniu „niezdefiniowany” nie jest jest słowem kluczowym w JavaScript i może mieć przypisaną wartość.
Najbardziej niezawodny sposób na wykonanie tego testu to:
if (typeof myVar === "undefined")
To zawsze zwraca poprawny wynik, a nawet radzi sobie z sytuacją, w której myVar
nie jest zadeklarowany.
var undefined = false; // Shockingly, this is completely legal!
if (myVar === undefined) {
alert("You have been misled. Run away!");
}
Dodatkowo myVar === undefined
spowoduje błąd w sytuacji, gdy myVar nie jest zgłoszony.
=== undefined
oszołomienia. Tak, możesz przypisać do undefined
, ale nie ma uzasadnionego powodu, aby to zrobić, i można przewidzieć, że może to spowodować uszkodzenie kodu. W C możesz #define true false
, aw Pythonie możesz przypisać True
i False
, ale ludzie nie czują potrzeby projektowania swojego kodu w tych językach w taki sposób, aby zabezpieczyć się przed możliwością celowego sabotowania własnego środowiska w innym miejscu kodu . Dlaczego undefined
warto tutaj przypisać nawet wartość?
void 0
aby uzyskać wartość, która undefined
wskazuje. Więc możesz to zrobić if (myVar === void 0)
. 0
nie jest wyjątkowy, można dosłownie umieścić dowolny wyraz tam.
undefined
. MDN: undefined
Pomimo tego, że jest gorąco polecany przez wiele innych odpowiedzi tutaj, typeof
jest złym wyborem . Nigdy nie należy go używać do sprawdzania, czy zmienne mają wartość undefined
, ponieważ działa to jako łączone sprawdzenie wartości undefined
i tego, czy zmienna istnieje. W zdecydowanej większości przypadków wiesz, kiedy istnieje zmienna, i typeof
po prostu wprowadzasz możliwość cichej awarii, jeśli popełnisz literówkę w nazwie zmiennej lub w literale ciągu '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!
}
Tak więc, chyba że wykonujesz wykrywanie typeof module !== 'undefined'
funkcji² , gdzie nie ma pewności, czy dana nazwa będzie objęta zakresem (np. Sprawdzanie jako krok w kodzie specyficznym dla środowiska CommonJS), typeof
jest szkodliwym wyborem, gdy jest używana w zmiennej, a poprawną opcją jest aby bezpośrednio porównać wartość:
var foo = …;
if (foo === undefined) {
⋮
}
Niektóre typowe nieporozumienia na ten temat obejmują:
że odczyt „niezainicjowanej” zmiennej ( var foo
) lub parametru ( function bar(foo) { … }
zwanego as bar()
) zakończy się niepowodzeniem. To po prostu nieprawda - zmienne bez wyraźnej inicjalizacji i parametry, którym nie podano wartości, zawsze stają się undefined
i zawsze mają zakres.
które undefined
można zastąpić. 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 Niezdefiniowana. Jednak od wersji ES5 ta właściwość jest tylko do odczytu i nie można jej konfigurować . Żadna nowoczesna przeglądarka nie pozwoli na zmianę undefined
właściwości, a od 2017 r. Ma to miejsce od dłuższego czasu. Brak trybu ścisłego również nie wpływa na undefined
zachowanie - po prostu powoduje, że wyrażenia takie jak „ undefined = 5
nic nie rób” zamiast rzucać. Ponieważ nie jest to słowo kluczowe, możesz zadeklarować zmienne o nazwie undefined
, a zmienne te można zmienić, tworząc ten kiedyś powszechny wzorzec:
(function (undefined) {
// …
})()
bardziej niebezpieczne niż używanie globalnego undefined
. Jeśli musisz być zgodny undefined
z ES3, zamień na void 0
- nie uciekaj się typeof
. ( void
zawsze był jednoargumentowym operatorem, który ocenia wartość niezdefiniowaną dla dowolnego argumentu).
Ponieważ zmienne działają na przeszkodzie, nadszedł czas, aby odpowiedzieć na rzeczywiste pytanie: właściwości obiektu. Nie ma powodu, aby kiedykolwiek używać typeof
właściwości obiektu. Wcześniejszy wyjątek dotyczący wykrywania funkcji nie ma tutaj zastosowania -typeof
ma on tylko specjalne zachowanie względem 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żne z tym3:
if (foo.bar === undefined) {
⋮
}
i biorąc pod uwagę powyższą poradę, aby uniknąć mylenia czytelników co do tego, dlaczego używasz typeof
, ponieważ najbardziej sensowne jest użycie ===
do sprawdzenia równości, ponieważ można ją ponownie sprawdzić, sprawdzając wartość zmiennej później, i ponieważ jest to po prostu zwykłe wygląda lepiej, zawsze należy również użyć === undefined
³ tutaj .
Jeśli chodzi o właściwości obiektu, należy wziąć pod uwagę jeszcze to, czy naprawdę chcesz to sprawdzić undefined
. Dana nazwa właściwości może być nieobecna na obiekcie (generując wartość undefined
podczas odczytu), być obecna na samym obiekcie z wartością undefined
, występować na prototypie obiektu z wartością undefined
lub być obecna na dowolnym z tych, które nie mają undefined
wartości. 'key' in obj
powie ci, czy klucz znajduje się gdzieś w łańcuchu prototypowym obiektu, i Object.prototype.hasOwnProperty.call(obj, 'key')
powie, czy jest bezpośrednio na obiekcie. Nie będę jednak szczegółowo omawiał odpowiedzi na temat prototypów i używania obiektów jako map z kluczem łańcuchowym, ponieważ ma to na celu przede wszystkim przeciwdziałanie wszelkim złym radom w innych odpowiedziach, niezależnie od możliwych interpretacji pierwotnego pytania. Czytaj dalejprototypy obiektów na MDN, aby uzyskać więcej!
¹ niezwykły wybór przykładowej nazwy zmiennej? to jest naprawdę martwy kod z rozszerzenia NoScript dla Firefoksa.
² nie zakładaj jednak, że nie wiadomo, co jest w zasięgu, jest ogólnie w porządku. dodatkowa wrażliwość spowodowana nadużyciem zakresu dynamicznego: Projekt Zero 1225
³ ponownie przyjmuje środowisko ES5 + i undefined
odnosi się do undefined
właściwości obiektu globalnego. zastąpić void 0
inaczej.
undefined
, ukrywając domyślny. Który dla większości praktycznych celów ma taki sam efekt jak nadpisanie go.
void 0
do porównania z nieokreślonym, ale znowu - to głupie i przesadne.
typeof something === "undefined")
w kodzie.
void 0
jest (raz) zarówno krótszy, jak i bezpieczniejszy! To zwycięstwo w mojej książce.
W JavaScript jest null i jest niezdefiniowany . Mają różne znaczenia.
Marijn Haverbeke w swojej bezpłatnej książce online „ Eloquent JavaScript ” (moje podkreślenie):
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 a zerowym jest głównie akademicka i zwykle niezbyt interesująca. W praktycznych programach często konieczne jest sprawdzenie, czy coś „ma wartość”. W takich przypadkach można użyć wyrażenia coś == niezdefiniowana, ponieważ nawet jeśli nie są one dokładnie tą samą wartością, wartość null == niezdefiniowana da wartość true.
Myślę, że najlepszym sposobem sprawdzenia, czy coś jest niezdefiniowane, byłoby:
if (something == undefined)
Mam nadzieję że to pomoże!
Edycja: 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
undefined
jest tylko zmienną, którą użytkownik może przypisać ponownie: pisanie undefined = 'a';
spowoduje, że kod przestanie robić to, co myślisz. Korzystanie typeof
jest lepsze i działa również w przypadku zmiennych (nie tylko właściwości), które nie zostały zadeklarowane.
Co to znaczy: „niezdefiniowana właściwość obiektu” ?
W rzeczywistości 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ść o nieokreślonej wartości . Spójrzmy na ten kod:
var o = { a: undefined }
Jest o.a
niezdefiniowany? Tak! Jego wartość jest nieokreślona. Jest o.b
niezdefiniowany? Pewnie! W ogóle nie ma właściwości „b”! OK, zobacz teraz, jak zachowują się różne podejścia 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
może wykryć sytuację, w której 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ć niezdefiniowana.
1) Chcesz wiedzieć, czy właściwość jest niezdefiniowana na podstawie pierwszego lub drugiego znaczenia (najbardziej typowa sytuacja).
obj.prop === undefined // IMHO, see "final fight" below
2) Chcesz tylko wiedzieć, czy obiekt ma jakąś właściwość i nie przejmuj się jego wartością.
'prop' in obj
x.a === undefined
lub to typeof x.a == 'undefined'
rośnie, ReferenceError: x is not defined
jeśli x nie jest zdefiniowane.undefined
jest zmienną globalną (tak więc faktycznie znajduje się window.undefined
w przeglądarkach). Jest obsługiwany od ECMAScript 1st Edition, a od ECMAScript 5 jest tylko do odczytu . Dlatego we współczesnych przeglądarkach nie można tego zmienić na prawdziwe, ponieważ wielu autorów lubi nas straszyć, ale nadal dotyczy to starszych przeglądarek.obj.prop === undefined
vstypeof obj.prop == 'undefined'
Plusy obj.prop === undefined
:
undefined
Wady obj.prop === undefined
:
undefined
można zastąpić w starych przeglądarkachPlusy typeof obj.prop == 'undefined'
:
Wady typeof obj.prop == 'undefined'
:
'undefned'
( niepoprawnie napisane ) tutaj jest tylko ciągiem ciągłym, więc silnik JavaScript nie może ci pomóc, jeśli źle napisałeś tak jak przed chwilą.Node.js obsługuje zmienną globalną undefined
jako global.undefined
(można jej również używać bez prefiksu „globalnego”). Nie wiem o innych implementacjach JavaScript po stronie serwera.
undefined
członkostwie global
. Również ani console.log(global);
nie for (var key in global) { ... }
jest niezdefiniowany jako członek globalny . Ale test jak 'undefined' in global
pokazuje odwrotnie.
[[Enumerable]]
to nieprawda :-)
Minuses of typeof obj.prop == 'undefined'
to, można tego uniknąć, pisząc jako typeof obj.prop == typeof undefined
. Daje to również bardzo ładną symetrię.
obj.prop === undefined
.
if ('foo' in o
)… twoja odpowiedź jest prawdziwa pierwsza poprawna odpowiedź tutaj. Prawie wszyscy inni po prostu odpowiadają na to zdanie.
Problem sprowadza się do trzech przypadków:
undefined
.undefined
.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 niestety typeof obj.foo
nie mówi nam, który z trzech przypadków mamy. Możemy jednak połączyć to z, "foo" in obj
aby rozróżnić 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 testy te są takie same dla null
wpisów
| typeof obj.x === 'undefined' | !("x" in obj)
{ x:null } | false | false
Twierdzę, że w niektórych przypadkach bardziej sensowne (i jest jaśniejsze) jest sprawdzenie, czy właściwość istnieje, niż sprawdzenie, czy jest ona niezdefiniowana, a jedynym przypadkiem, w którym ta kontrola będzie inna, jest przypadek 2, rzadki przypadek rzeczywisty wpis w obiekcie o nieokreślonej wartości.
Na przykład: Właśnie refaktoryzowałem pęk kodu, który zawierał kilka sprawdzeń, czy obiekt ma daną właściwość.
if( typeof blob.x != 'undefined' ) { fn(blob.x); }
Co było wyraźniejsze, gdy napisano bez czeku na niezdefiniowane.
if( "x" in blob ) { fn(blob.x); }
Ale jak już wspomniano, nie są one dokładnie takie same (ale są wystarczająco dobre dla moich potrzeb).
if (!("x" in blob)) {}
z nawiasami wokół, ponieważ! operator ma pierwszeństwo przed „w”. Mam nadzieję, że komuś pomoże.
a = {b: undefined}
; wtedy typeof a.b === typeof a.c === 'undefined'
ale 'b' in a
i !('c' in a)
.
{ x : undefined }
lub przynajmniej dodanie go jako kolejnej alternatywy dla (2.) w tabeli - musiałem pomyśleć przez chwilę, aby zdać sobie sprawę, że punkt (2.) ocenia undefined
(chociaż wspominasz o tym później).
if ( typeof( something ) == "undefined")
To działało dla mnie, podczas gdy inni nie.
typeof (something == "undefined")
.
(typeof something) === "undefined"
.
Nie jestem pewien, gdzie pochodzenie korzystania ===
ze typeof
pochodzi, jak i konwencji widzę to stosowane w wielu bibliotekach, ale operator typeof zwraca ciągiem znaków, a wiemy, że góry, więc dlaczego chcesz także rodzaj też to sprawdzić?
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
==
nadal wymaga co najmniej sprawdzenia typu - interpreter nie może porównać dwóch operandów, nie znając najpierw ich typu.
==
jest o jedną postać mniej niż ===
:)
Przeniesienie odpowiedzi z powiązanego pytania Jak sprawdzić, czy w JavaScript jest „niezdefiniowany”?
Specyficzne dla tego pytania, patrz 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
do in
testów robi różnicę, gdy znajduje się w opakowaniu z lunetą)
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
Jeśli zrobisz
if (myvar == undefined )
{
alert('var does not exists or is not initialized');
}
zakończy się niepowodzeniem, gdy zmienna myvar
nie istnieje, ponieważ myvar nie jest zdefiniowany, więc skrypt jest zepsuty, a test nie ma wpływu.
Ponieważ obiekt okna ma zasięg globalny (obiekt domyślny) poza funkcją, deklaracja zostanie „dołączona” do obiektu okna.
Na przykład:
var myvar = 'test';
Zmienna globalna myvar jest taka sama jak window.myvar lub window ['myvar']
Aby uniknąć błędów w testowaniu, gdy istnieje zmienna globalna, lepiej użyć:
if(window.myvar == undefined )
{
alert('var does not exists or is not initialized');
}
Pytanie, czy zmienna naprawdę istnieje, nie ma znaczenia, jej wartość jest niepoprawna. W przeciwnym razie głupio jest inicjalizować zmienne z niezdefiniowanym i lepiej jest użyć wartości false do inicjalizacji. Kiedy wiesz, że wszystkie deklarowane przez ciebie zmienne są inicjalizowane wartością false, możesz po prostu sprawdzić jego typ lub polegać na !window.myvar
sprawdzeniu, czy ma on prawidłową / prawidłową wartość. Nawet jeśli zmienna nie jest zdefiniowana, to !window.myvar
jest taka sama dla myvar = undefined
lub myvar = false
lub myvar = 0
.
Gdy oczekujesz określonego typu, sprawdź typ zmiennej. Aby przyspieszyć testowanie stanu, lepiej:
if( !window.myvar || typeof window.myvar != 'string' )
{
alert('var does not exists or is not type of string');
}
Gdy pierwszy i prosty warunek jest spełniony, tłumacz pomija kolejne testy.
Zawsze lepiej jest użyć instancji / obiektu zmiennej, aby sprawdzić, czy uzyskała prawidłową wartość. Jest bardziej stabilny i stanowi lepszy sposób programowania.
(y)
Nie widziałem (mam nadzieję, że nie tęskniłem) nikogo sprawdzającego obiekt przed nieruchomością. Jest to więc najkrótszy i najskuteczniejszy (choć niekoniecznie najbardziej wyraźny):
if (obj && obj.prop) {
// Do something;
}
Jeśli obiekt obj lub obj.prop jest niezdefiniowany, null lub „falsy”, instrukcja if nie wykona bloku kodu. Jest to zwykle pożądane zachowanie w większości instrukcji bloków kodu (w JavaScript).
var x = obj && obj.prop || 'default';
W artykule Exploring the Abyss of Null and Undefined in JavaScript przeczytałem, że frameworki takie jak Underscore.js używają tej funkcji:
function isUndefined(obj){
return obj === void 0;
}
void 0
to tylko krótki sposób pisania undefined
(ponieważ to właśnie pustka, po której następuje zwrot wyrażenia), oszczędza 3 znaki. Mógłby to zrobić var a; return obj === a;
, ale to jeszcze jedna postać. :-)
void
jest słowem zastrzeżonym, podczas gdy undefined
nie jest, tzn. gdy domyślnie undefined
jest równe void 0
, możesz przypisać wartość undefined
np undefined = 1234
.
isUndefined(obj)
: 16 znaków. obj === void 0
: 14 znaków. - powiedział mniej więcej.
Po prostu wszystko nie jest zdefiniowane w JavaScript, jest niezdefiniowane , nie ma znaczenia, czy jest to właściwość wewnątrz Object / Array, czy tylko zwykła zmienna ...
JavaScript ma, typeof
dzięki czemu bardzo łatwo jest wykryć niezdefiniowaną zmienną.
Wystarczy sprawdzić, czy typeof whatever === 'undefined'
i zwróci wartość logiczną.
Tak isUndefined()
napisano słynną funkcję w AngularJs v.1x:
function isUndefined(value) {return typeof value === 'undefined';}
Gdy zobaczysz, że funkcja odbiera wartość, jeśli ta wartość jest zdefiniowana, zwróci false
, w przeciwnym razie zwróci wartość dla niezdefiniowanych wartości true
.
Spójrzmy więc, jakie będą wyniki, gdy przekażemy wartości, w tym właściwości obiektu jak poniżej, oto lista zmiennych, które mamy:
var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;
i sprawdzamy je jak poniżej, możesz zobaczyć wyniki przed nimi jako komentarz:
isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true
Jak widzisz, możemy sprawdzić wszystko za pomocą czegoś takiego w naszym kodzie, jak wspomniano, możesz po prostu użyć typeof
w kodzie, ale jeśli używasz go w kółko, utwórz funkcję podobną do próbki kątowej, którą udostępniam i nadal używam jako zgodnie ze wzorem kodu DRY.
I jeszcze jedno, aby sprawdzić właściwość obiektu w prawdziwej aplikacji, której nie jesteś pewien, czy nawet obiekt istnieje, sprawdź, czy obiekt istnieje wcześniej.
Jeśli zaznaczysz właściwość obiektu, a obiekt nie istnieje, zgłosi błąd i zatrzyma działanie całej aplikacji.
isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)
Tak proste, że możesz zawinąć w instrukcję if, taką jak poniżej:
if(typeof x !== 'undefined') {
//do something
}
Co również równe jest Zdefiniowane w Angular 1.x ...
function isDefined(value) {return typeof value !== 'undefined';}
Również inne frameworki javascript, takie jak podkreślenie, mają podobną kontrolę definiującą, ale zalecam użycie, typeof
jeśli już nie używasz żadnych frameworków.
Dodałem również tę sekcję z MDN, która zawiera przydatne informacje na temat typeof, undefined i void (0).
Ścisła równość i nieokreślone
Można użyć operatorów niezdefiniowanych i ścisłych równości i nierówności, aby ustalić, czy zmienna ma wartość. W poniższym kodzie zmienna x nie jest zdefiniowana, a instrukcja if ma wartość true.
var x;
if (x === undefined) {
// these statements execute
}
else {
// these statements do not execute
}
Uwaga: Należy tutaj zastosować operator ścisłej równości zamiast standardowego operatora równości, ponieważ x == undefined sprawdza również, czy x jest zerowy, podczas gdy ścisła równość nie. wartość null nie jest równoważna niezdefiniowanemu. Zobacz szczegóły operatorów.
Operator
typeof i nieokreślony Alternatywnie można użyć typeof:
var x;
if (typeof x === 'undefined') {
// these statements execute
}
Jednym z powodów użycia typeof jest to, że nie zgłasza błędu, jeśli zmienna nie została zadeklarowana.
// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
// these statements execute
}
if (x === undefined) { // throws a ReferenceError
}
Tego rodzaju techniki należy jednak unikać. JavaScript jest językiem o statycznym zasięgu, więc wiedząc, czy zmienna jest zadeklarowana, można ją odczytać, sprawdzając, czy jest zadeklarowana w otaczającym kontekście. Jedynym wyjątkiem jest zakres globalny, ale zasięg globalny jest powiązany z obiektem globalnym, więc sprawdzenie istnienia zmiennej w kontekście globalnym można wykonać, sprawdzając istnienie właściwości obiektu globalnego (używając operatora in, na przykład).
Nieważny operator i nieokreślony
Operator void jest trzecią alternatywą.
var x;
if (x === void 0) {
// these statements execute
}
// y has not been declared before
if (y === void 0) {
// throws a ReferenceError (in contrast to `typeof`)
}
więcej> tutaj
Najprawdopodobniej chcesz if (window.x)
. Ta kontrola jest bezpieczna, nawet jeśli x nie został zadeklarowany ( var x;
) - przeglądarka nie zgłasza błędu.
if (window.history) {
history.call_some_function();
}
window jest obiektem, który przechowuje wszystkie zmienne globalne jako swoje elementy, a próba uzyskania dostępu do nieistniejącego elementu jest legalna. Jeśli x nie zostało zadeklarowane lub nie zostało ustawione, wówczas window.x
zwraca niezdefiniowane . niezdefiniowana prowadzi do fałszu, gdy if () ją ocenia.
typeof history != 'undefined'
faktycznie działa w obu systemach.
Czytając to, jestem zdumiony, że tego nie widziałem. Znalazłem wiele algorytmów, które by do tego pasowały.
Jeśli wartość obiektu nigdy nie została zdefiniowana, uniemożliwi to powrót, true
jeśli zostanie zdefiniowana jako null
lub undefined
. Jest to pomocne, jeśli chcesz zwrócić wartość true dla wartości ustawionych jakoundefined
if(obj.prop === void 0) console.log("The value has never been defined");
Jeśli chcesz, aby wynik był taki jak true
dla wartości zdefiniowanych wartością undefined
lub nigdy nie został zdefiniowany, możesz po prostu użyć=== undefined
if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");
Często ludzie pytają mnie o algorytm, aby dowiedzieć się, czy wartość jest fałszem undefined
, lub null
. Następujące prace.
if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
console.log("The value is falsy, null, or undefined");
}
if (!obj.prop)
var obj = {foo: undefined}; obj.foo === void 0
-> true
. Jak to się „nigdy nie definiuje jako undefined
”? To jest źle.
Porównaj z void 0
, dla zwięzłości.
if (foo !== void 0)
To nie jest tak gadatliwe jak if (typeof foo !== 'undefined')
foo
zostanie zgłoszony.
Rozwiązanie jest nieprawidłowe. W JavaScript
null == undefined
zwróci wartość true, ponieważ oba są „rzutowane” na wartość logiczną i są fałszywe. Prawidłowym sposobem byłoby sprawdzenie
if (something === undefined)
który jest operatorem tożsamości ...
===
to równość typu + (pierwotna równość | tożsamość obiektu), gdzie pierwotne obejmują łańcuchy. Myślę, że większość ludzi uważa za 'abab'.slice(0,2) === 'abab'.slice(2)
nieintuicyjne, jeśli ktoś uważa się ===
za operatora tożsamości.
Możesz uzyskać tablicę ze wszystkimi niezdefiniowanymi ścieżkami, używając następującego kodu.
function getAllUndefined(object) {
function convertPath(arr, key) {
var path = "";
for (var i = 1; i < arr.length; i++) {
path += arr[i] + "->";
}
path += key;
return path;
}
var stack = [];
var saveUndefined= [];
function getUndefiend(obj, key) {
var t = typeof obj;
switch (t) {
case "object":
if (t === null) {
return false;
}
break;
case "string":
case "number":
case "boolean":
case "null":
return false;
default:
return true;
}
stack.push(key);
for (k in obj) {
if (obj.hasOwnProperty(k)) {
v = getUndefiend(obj[k], k);
if (v) {
saveUndefined.push(convertPath(stack, k));
}
}
}
stack.pop();
}
getUndefiend({
"": object
}, "");
return saveUndefined;
}
Link do jsFiddle
getUndefiend
powinno być getUndefined
.
Oto moja sytuacja:
Korzystam z wyniku wywołania REST. Wynik należy przeanalizować z JSON do obiektu JavaScript.
Jest jeden błąd, którego muszę bronić. Jeśli argumenty wywołania reszty były niepoprawne, o ile użytkownik podał błędne argumenty, wywołanie reszty wraca w zasadzie puste.
Korzystając z tego postu, aby pomóc mi się przed tym bronić, próbowałem tego.
if( typeof restResult.data[0] === "undefined" ) { throw "Some error"; }
W mojej sytuacji, jeśli restResult.data [0] === "obiekt", to mogę bezpiecznie rozpocząć sprawdzanie reszty elementów. Jeśli nie jest zdefiniowany, wyrzuć błąd jak wyżej.
Mówię tylko, że w mojej sytuacji wszystkie powyższe sugestie nie zadziałały. Nie mówię, że mam rację i wszyscy się mylą. W ogóle nie jestem mistrzem JavaScript, ale mam nadzieję, że to komuś pomoże.
typeof
strażnik tak naprawdę nie chroni przed niczym, z czym nie poradziłoby sobie bezpośrednie porównanie. Jeśli restResult
jest niezdefiniowany lub niezadeklarowany, nadal będzie rzucał.
if(!restResult.data.length) { throw "Some error"; }
Istnieje przyjemny i elegancki sposób przypisania zdefiniowanej właściwości do nowej zmiennej, jeśli jest ona zdefiniowana, lub przypisania jej wartości domyślnej jako rezerwowej, jeśli jest niezdefiniowana.
var a = obj.prop || defaultValue;
Jest odpowiedni, jeśli masz funkcję, która otrzymuje dodatkową właściwość config:
var yourFunction = function(config){
this.config = config || {};
this.yourConfigValue = config.yourConfigValue || 1;
console.log(this.yourConfigValue);
}
Teraz wykonywana
yourFunction({yourConfigValue:2});
//=> 2
yourFunction();
//=> 1
yourFunction({otherProperty:5});
//=> 1
Wszystkie odpowiedzi są niekompletne. To jest właściwy sposób, aby wiedzieć, że istnieje właściwość „zdefiniowana jako niezdefiniowana”:
var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;
Przykład:
var a = { b : 1, e : null } ;
a.c = a.d ;
hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null
// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined
Szkoda, że to była prawidłowa odpowiedź zakopana w złych odpowiedziach> _ <
Dla każdego, kto przejedzie, dam ci niezdefiniowane za darmo !!
var undefined ; undefined ; // undefined
({}).a ; // undefined
[].a ; // undefined
''.a ; // undefined
(function(){}()) ; // undefined
void(0) ; // undefined
eval() ; // undefined
1..a ; // undefined
/a/.a ; // undefined
(true).a ; // undefined
Przeglądając komentarze, dla tych, którzy chcą sprawdzić oba, jest niezdefiniowana lub jej wartość jest null:
//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
alert('either it is undefined or value is null')
}
Jeśli używasz biblioteki jQuery jQuery.isEmptyObject()
, wystarczy w obu przypadkach,
var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;
s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;
//Usage
if (jQuery.isEmptyObject(s)) {
alert('Either variable:s is undefined or its value is null');
} else {
alert('variable:s has value ' + s);
}
s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;
Jeśli używasz Angulara:
angular.isUndefined(obj)
angular.isUndefined(obj.prop)
Underscore.js:
_.isUndefined(obj)
_.isUndefined(obj.prop)
1
do zmiennej x
? Czy potrzebuję podkreślenia lub jQuery? (niesamowite, że ludzie będą używać bibliotek do nawet najbardziej podstawowych operacji, takich jak typeof
czek)
Używam if (this.variable)
do testowania, czy to jest zdefiniowane. Proste if (variable)
, zalecane powyżej , zawodzi dla mnie. Okazuje się, że działa tylko wtedy, gdy zmienna jest polem jakiegoś obiektu, obj.someField
aby sprawdzić, czy jest zdefiniowana w słowniku. Ale możemy użyć this
lub window
jako obiektu słownika, ponieważ jakakolwiek zmienna jest polem w bieżącym oknie, tak jak ja to rozumiem. Dlatego tutaj jest test
if (this.abc) alert("defined"); else alert("undefined");
abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");
Najpierw wykrywa, że zmienna abc
jest niezdefiniowana i jest definiowana po inicjalizacji.
Podaję tutaj trzy sposoby dla tych, którzy oczekują dziwnych odpowiedzi:
function isUndefined1(val) {
try {
val.a;
} catch (e) {
return /undefined/.test(e.message);
}
return false;
}
function isUndefined2(val) {
return !val && val+'' === 'undefined';
}
function isUndefined3(val) {
const defaultVal={};
return ((input=defaultVal)=>input===defaultVal)(val);
}
function test(func){
console.group(`test start :`+func.name);
console.log(func(undefined));
console.log(func(null));
console.log(func(1));
console.log(func("1"));
console.log(func(0));
console.log(func({}));
console.log(func(function () { }));
console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);
Spróbuj uzyskać właściwość wartości wejściowej, sprawdź komunikat o błędzie, jeśli istnieje. Jeśli wartość wejściowa jest niezdefiniowana, komunikat o błędzie brzmiałby: Nieprzechwycony typ błędu : Nie można odczytać właściwości „b” niezdefiniowanej
Konwertuj wartość wejściową na ciąg znaków, aby porównać "undefined"
i upewnij się, że jest to wartość ujemna.
W js parametr opcjonalny działa, gdy wartość wejściowa jest dokładnie undefined
.
function isUnset(inp) {
return (typeof inp === 'undefined')
}
Zwraca false, jeśli zmienna jest ustawiona, a true, jeśli jest niezdefiniowana.
Następnie użyj:
if (isUnset(var)) {
// initialize variable here
}
typeof
testu w funkcji. Niesamowite, że 4 osoby głosowały za tym. -1.
Chciałbym pokazać ci coś, czego używam w celu ochrony undefined
zmiennej:
Object.defineProperty(window, 'undefined', {});
To zabrania nikomu zmiany window.undefined
wartości, a tym samym niszczenia kodu na podstawie tej zmiennej. Jeśli używasz "use strict"
, wszystko, co próbuje zmienić jego wartość, zakończy się błędem, w przeciwnym razie zostanie po cichu zignorowane.
możesz także użyć proxy, będzie działać z zagnieżdżonymi wywołaniami, ale będzie wymagał jednego dodatkowego sprawdzenia:
function resolveUnknownProps(obj, resolveKey) {
const handler = {
get(target, key) {
if (
target[key] !== null &&
typeof target[key] === 'object'
) {
return resolveUnknownProps(target[key], resolveKey);
} else if (!target[key]) {
return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
}
return target[key];
},
};
return new Proxy(obj, handler);
}
const user = {}
console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }
więc użyjesz go jak:
const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
// do someting
}
Z lodash.js.
var undefined;
function isUndefined(value) {
return value === undefined;
}
Tworzy zmienną LOCAL o nazwie, undefined
która jest inicjowana wartością domyślną - rzeczywistą undefined
, a następnie porównywana value
ze zmienną undefined
.
Aktualizacja 9.09.2019
Odkryłem, że lodash zaktualizował jego wdrożenie. Zobacz mój problem i kod .
Aby być kuloodpornym, po prostu użyj:
function isUndefined(value) {
return value === void 0;
}