Czy istnieje standardowa funkcja sprawdzania zmiennych JavaScript, niezdefiniowanych lub pustych?

2258

Czy istnieje uniwersalna funkcja JavaScript, która sprawdza, czy zmienna ma wartość i upewnia się, że nie jest, undefinedlub null? Mam ten kod, ale nie jestem pewien, czy obejmuje on wszystkie przypadki:

function isEmpty(val){
    return (val === undefined || val == null || val.length <= 0) ? true : false;
}
Alex
źródło
5
możliwy duplikat Jak sprawdzić pusty ciąg w JavaScript?
Dour High Arch
78
Protip, nigdy nie rób (truthy statement) ? true : false;. Po prostu zrób (truthy statement);.
David Baucum
5
@GeorgeJempty nie jest dup, ponieważ druga odpowiedź dotyczy w szczególności łańcuchów , podczas gdy ta dotyczy zmiennych .
Madbreaks
2
Każda poprawna odpowiedź na to pytanie zależy całkowicie od tego, jak zdefiniujesz „puste”.
Madbreaks
3
@Jay To nie zaszkodzi, jeśli chodzi o wykonanie kodu. To po prostu zbyt szczegółowe. Nie powiedziałbyś: „Czy jesteś głodny, to prawda?” Po prostu „Jesteś głodny” Więc w kodzie po prostu powiedz if (hungry) …zamiast if (hungry === true) …. Podobnie jak wszystkie elementy kodujące w ten sposób, to tylko kwestia gustu. Bardziej konkretnie w przykładzie podanym przez OP, mówi jeszcze bardziej dosadnie: „Jeśli to prawda, to prawda, jeśli nie to fałsz”. Ale jeśli to prawda, to już jest prawdą. A jeśli to fałsz, to już jest fałsz. Jest to podobne do powiedzenia „Jeśli jesteś głodny, to jesteś, a jeśli nie, to nie jesteś”.
David Baucum

Odpowiedzi:

4376

Możesz po prostu sprawdzić, czy zmienna ma truthywartość, czy nie. To znaczy

if( value ) {
}

oceni, trueczy nievalue jest :

  • zero
  • nieokreślony
  • NaN
  • pusta struna ("")
  • 0
  • fałszywe

Powyższa lista przedstawia wszystkie możliwe falsywartości w ECMA- / Javascript. Znajdź go w specyfikacji w ToBooleansekcji.

Ponadto, jeśli nie wiesz, czy zmienna istnieje (to znaczy, jeśli została zadeklarowana ), powinieneś sprawdzić u typeofoperatora. Na przykład

if( typeof foo !== 'undefined' ) {
    // foo could get resolved and it's defined
}

Jeśli możesz być pewien, że zmienna jest przynajmniej zadeklarowana, powinieneś bezpośrednio sprawdzić, czy ma truthywartość jak pokazano powyżej.

Czytaj dalej: http://typeofnan.blogspot.com/2011/01/typeof-is-fast.html

jAndy
źródło
110
Co jeśli wartość jest fałszywą wartością logiczną, która była zamierzona. Czasami chcesz podać wartość domyślną, jeśli nie ma wartości, która nie zadziała, jeśli zostanie przekazany fałszywy boolean.
TruMan1,
100
@ TruMan1: w takim przypadku (gdzie twoja logika decyduje o sprawdzeniu poprawności) musisz iść podobnie if( value || value === false ). To samo dotyczy wszystkich wartości fałszowania , musimy je wyraźnie zweryfikować.
jAndy
28
Z wyjątkiem jeśli wartość jest tablicą. Interpretacja truthymoże być myląca. W takim przypadku powinniśmy sprawdzić, czy value.length != 0nie jest pusta tablica.
użytkownik
12
Tylko dodać, że jeśli czujesz ifkonstrukt jest składniowo zbyt ciężki, można użyć potrójny operatora, tak jak poniżej: var result = undefined ? "truthy" : "falsy". Lub jeśli po prostu chcesz, aby zmusić do wartości logicznej, użyj !!operatora, na przykład !!1 // true, !!null // false.
KFL
7
Zauważ też, że nie będzie to sprawdzać ciągów znaków, które zawierają tylko znaki spacji.
Christophe Roussy
220

Pełna metoda sprawdzania, czy wartość jest niezdefiniowana, czy null to:

return value === undefined || value === null;

Możesz także użyć ==operatora, ale wymaga to znajomości wszystkich zasad :

return value == null; // also returns true if value is undefined
Salman A.
źródło
33
Sprawdzanie tylko nullczy undefinedmożna zrobić tak: if (value == null). Uważaj na ==operatora, który naciska. Jeśli to if (value === null || value === undefined)zrobisz, zapomnisz / nie wiesz, jak wymusza Javascript. webreflection.blogspot.nl/2010/10/…
Christiaan Westerbeek
32
@ChristiaanWesterbeek: twój punkt, który arg == nulldaje takie same wyniki jak arg === undefined || arg === null. Uważam jednak ten drugi przykład za bardziej czytelny.
Salman A
10
arg == nulljest dość powszechne w moim doświadczeniu.
Bryan Downing,
8
return value === (void 0)jest bezpieczniejsze niż testowanie, undefinedktóre może być niestety uzasadnioną zmienną w zakresie.
x0n
4
@Sharky Istnieje różnica między zmienną, która jest niezdefiniowana, a zmienną niezadeklarowaną: lucybain.com/blog/2014/null-undefined-undeclared
Christiaan Westerbeek
79
function isEmpty(value){
  return (value == null || value.length === 0);
}

To zwróci prawdę dla

undefined  // Because undefined == null

null

[]

""

i zero funkcji argumentu, ponieważ funkcja lengthjest liczbą deklarowanych parametrów, którą przyjmuje.

Aby wyłączyć tę ostatnią kategorię, możesz po prostu sprawdzić puste ciągi znaków

function isEmpty(value){
  return (value == null || value === '');
}
Mike Samuel
źródło
7
undefined == nullaleundefined !== null
Ian Boyd
2
@IanBoyd to dlatego, że porównujesz == do ===. oznacza to, że undefined == null (true) undefined! = null (false) undefined === null (false) undefined! == null (true) lepiej podać nieco więcej informacji, aby być pomocnym i popychać ludzi w dobrym kierunku. moz doc na różnicę developer.mozilla.org/en-US/docs/Web/JavaScript/…
Corey Young
43

To jest najbezpieczniejszy czek i nie widziałem go tutaj dokładnie takiego:

if (typeof value !== 'undefined' && value) {
    //deal with value'
};

Obejmie przypadki, w których wartość nigdy nie została zdefiniowana, a także dowolne z tych:

  • zero
  • undefined (wartość undefined nie jest tym samym co parametr, który nigdy nie został zdefiniowany)
  • 0
  • "" (pusta struna)
  • fałszywe
  • NaN

Edytowano: Zmieniono na ścisłą równość (! ==), ponieważ jest to już norma;)

guya
źródło
10
Nie przegłosowałem, ale w odniesieniu do ścisłego porównania równości ogólna zasada jest taka, że ​​o ile nie potrzebujesz niejawnej konwersji typów, należy stosować ścisłe porównanie.
J.Steve,
2
Dzięki za komentarz, Steve. Ta ogólna zasada jest w porządku. Po prostu oczekuję, że ppl zrozumie, dlaczego używają jednego lub drugiego. Każdy sposób, w jaki wyglądasz, jest dla Ciebie przyjemnością, aby głosić o „zawsze używaj surowo” - tak jakby to była najważniejsza rzecz w Javascript. Widziałem zbyt wiele przypadków, takich jak if (val! == null), które oczywiście prowadzą do niepożądanych rezultatów. Można powiedzieć, że w razie wątpliwości - stosuj surowe, ale lepiej nie mieć wątpliwości.
guya,
6
Myślę, że chodzi tutaj o to, że oczekujemy, że typeofoperator zwróci łańcuch, więc użycie ścisłej kontroli równości jest technicznie dokładniejsze, bardziej precyzyjne i szybsze. Tak naprawdę nie ma powodu, aby korzystać z luźnego porównania, a nie na odwrót. Również val !== nullw wielu przypadkach jest całkowicie poprawny - robię to cały czas. Zgadzam się z twoim argumentem niezgodności, ale myślę, że jest to słaby przykład, aby sobie z tym poradzić. Nie próbuję cię trollować.
Bryan Downing,
Dzięki za komentarz Bryan, używasz val! == null, ponieważ wiesz, co robisz. Początkujący będzie chciał wrócić do sytuacji, gdy Val jest falsy. Ale val nigdy nie będzie zerowy, będzie niezdefiniowany. Gdyby tylko nie posłuchał tej rady, by „zawsze stosować surowo”, będzie miał mniej błędów. Widziałem, że tak się dzieje w kodzie produkcyjnym. typeof zawsze zwraca łańcuch, a diff prędkości będzie zbędny. Zatem jedynym argumentem przemawiającym za zastosowaniem ścisłego w powyższym przypadku jest spójność. Powiedziałem „Nie ma potrzeby ścisłej równości”. Nie oznacza to, że nie możesz, jeśli chcesz, lub jeśli poprawia to spójność kodu.
guya,
28

Przydatna może być następująca funkcja:

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

Lub w ES7 (komentarz, jeśli dalsze ulepszenia)

function typeOf(obj) {
  const { toString } = Object.prototype;
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);

  return type.toLowerCase();
}

Wyniki:

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map

„Zauważ, że operator bind (: :) nie jest częścią ES2016 (ES7) ani żadnej późniejszej edycji standardu ECMAScript. Jest to obecnie propozycja etapu 0 (strawman) do wprowadzenia do języka.” - Simon Kjellberg. autor pragnie dodać swoje poparcie dla tej pięknej propozycji otrzymania królewskiego wstąpienia.

Vix
źródło
+1 dobrze jest znać obiekt typu „regexp” , „array” i „function”
Yash
@Vix, dlaczego wersja ES7 jest lepsza?
GollyJer
Nie jest, eksperymentował z bardziej czytelnymi sposobami wyrażania tej samej funkcjonalności, wykorzystując: przypisanie destrukcyjne, operator bind.
Vix
2
Należy zauważyć, że operator bind ( ::) nie jest częścią ES2016 (ES7) ani żadnej późniejszej edycji standardu ECMAScript. Obecnie jest to propozycja etapu 0 (strawman) dotycząca wprowadzenia do języka.
Simon Kjellberg,
25

Pierwsza odpowiedź z najlepszą oceną jest błędna. Jeśli wartość jest niezdefiniowana, spowoduje to wyjątek we współczesnych przeglądarkach. Musisz użyć:

if (typeof(value) !== "undefined" && value)

lub

if (typeof value  !== "undefined" && value)
krupar
źródło
3
eee ... Myślę, że to źle, jakby (wartość) była wystarczająca (z wyjątkiem pustych obiektów / tablic). jeśli wartość jest „niezdefiniowana”, konfesjonał „jeśli” nie przejdzie.
Oskar Szura
3
To łączy zmienne, które nie są zdefiniowane (które zgłaszają błąd ReferenceError), które różnią się od zmiennych o undefinedwartości.
Qantas 94 Heavy
2
Mam ten sam błąd tutaj. if (x), if (! x), if (!! x) wyrzuci błąd, jeśli x jest niezdefiniowany.
shaosh,
if(value === 0) gameOver(); ;)
Madbreaks
Ta odpowiedź jest również błędna, ponieważ zwraca false, gdy valuewynosi zero, co nie jest tym, czego szuka operacja.
Madbreaks
17

Ten warunek sprawdź

if (!!foo) {
    //foo is defined
}

to wszystko czego potrzebujesz.

JerryP
źródło
Zakładam, że to tylko fragment. Ale ifjuż wykonuje kontrolę fałszowania, którą to po prostu zamienia na wartość logiczną. Czy łapie jakieś przypadki, których normalny if(foo)nie łapie?
Daan van Hulst
1
Jest to idealne rozwiązanie, gdy potrzebujesz czegoś wbudowanego, na przykład potrzebuję atrybutu reagowania (zwanego aktywnym), który jest prawdziwy, gdy ciąg znaków nie jest pusty - instrukcja if byłaby nadmierna, więc mogę po prostu użyćactive={!!foo}
Ben Kolya Mansley
16

! Sprawdź puste ciągi znaków („”), null, undefined, false oraz liczbę 0 i NaN. Powiedz, jeśli ciąg jest pusty, var name = ""wówczas console.log(!name)zwraca true.

function isEmpty(val){
  return !val;
}

funkcja zwróci true, jeśli val jest puste, null, niezdefiniowane, false, liczba 0 lub NaN .

LUB

W zależności od domeny problemu możesz użyć po prostu jak !vallub !!val.

Arif
źródło
To tak naprawdę nie mówi, czy zmienna jest pusta, ponieważ fałsz i 0 mogą być prawidłowymi wartościami i nie mogą stanowić pustej wartości. Wartość funkcji isEmpty polega na upewnieniu się, że oczekiwane wartości, które są puste, zwracają wartość true. moim zdaniem wartości zerowe, niezdefiniowane, NaN i pusty ciąg to wartości, które mają sens jako puste.
Corey Young
9
Po co korzystać, isEmpty(val)jeśli możesz to zrobić !val?
Allen Linatoc
To zależy od Ciebie. Możesz go użyć do zwiększenia czytelności. W przeciwnym razie, jeśli uważasz, że zespół, w którym pracujesz, jest bardziej zaawansowanym programistą, możesz użyć tylko !vallub w !!valzależności od domeny problemu.
Arif
15

Rozwiązanie, które bardzo lubię:

Zdefiniujmy, że pusta zmienna ma wartość nulllub undefined, lub jeśli ma długość, jest równa zero lub jeśli jest obiektem, nie ma kluczy:

function isEmpty (value) {
  return (
    // null or undefined
    (value == null) ||

    // has length and it's zero
    (value.hasOwnProperty('length') && value.length === 0) ||

    // is an Object and has no keys
    (value.constructor === Object && Object.keys(value).length === 0)
  )
}

Zwroty:

  • prawda: undefined , null, "", [],{}
  • false: true , false, 1, 0, -1, "foo", [1, 2, 3],{ foo: 1 }
Alexandre Magro
źródło
14

Trochę przesadzasz. Aby sprawdzić, czy zmienna nie ma wartości, wystarczy sprawdzić przed niezdefiniowanym i zerowym.

function isEmpty(value){
    return (typeof value === "undefined" || value === null);
}

Zakłada się 0, że ""obiekty (nawet pusty obiekt i tablica) są prawidłowymi „wartościami”.

tcooc
źródło
10

Jeśli wolisz zwykły JavaScript, spróbuj tego:

  /**
   * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
   * length of `0` and objects with no own enumerable properties are considered
   * "empty".
   *
   * @static
   * @memberOf _
   * @category Objects
   * @param {Array|Object|string} value The value to inspect.
   * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
   * @example
   *
   * _.isEmpty([1, 2, 3]);
   * // => false
   *
   * _.isEmpty([]);
   * // => true
   *
   * _.isEmpty({});
   * // => true
   *
   * _.isEmpty('');
   * // => true
   */

function isEmpty(value) {
    if (!value) {
      return true;
    }
    if (isArray(value) || isString(value)) {
      return !value.length;
    }
    for (var key in value) {
      if (hasOwnProperty.call(value, key)) {
        return false;
      }
    }
    return true;
  }

W przeciwnym razie, jeśli już używasz podkreślenia lub lodash, spróbuj:

_.isEmpty(value)
l3x
źródło
3
Wypróbowałem Twój kod. W konsoli pojawia się komunikat o błędzie: „Błąd nieprzechwyconego odwołania: isArray () nie jest zdefiniowany”. W przeciwnym razie byłoby świetnie, gdyby zadziałało.
crmprogdev
11
Przynajmniej w przypadku lodash _.isNiljest funkcja, której szukasz _.isEmpty. Dokumentacja isNil , dokumentacja isEmpty
Snixtor
To się nie powiedzie, jeśli wartość ma wartość logiczną i ma wartość true.
kalyanbk
3
Zwykły javascript nie ma isArraylub nie isStringdziała na window.
GFoley83
@ GFoley83 - Złapałeś mnie! Mam powody, dla których nie używam systemu Windows. Właściwie omawiam ten temat w rozdziale, który mówi o historii i postępach języków oprogramowania. Bardziej istotnymi informacjami będą prawdopodobnie dyskusja / kod demonstrujący obsługę błędów monadycznych w mojej książce „Naucz się programowania funkcjonalnego w Go”. Twoje zdrowie!
l3x
9

Oto moja - zwraca true, jeśli wartość jest pusta, niezdefiniowana itp. Lub pusta (tzn. Zawiera tylko puste spacje):

function stringIsEmpty(value) {

    return value ? value.trim().length == 0 : true;

}
DavidWainwright
źródło
1
Zrobiłem tutaj test na kilka metod. Po sprawdzeniu niezdefiniowanej funkcja działa świetnie. Więc używam if (typeof value! == 'undefined' &&! IsEmpty (value)) LUB, jeśli faktycznie chcesz sprawdzić, czy jest pusty, możesz użyć if (typeof value === 'undefined' || IsEmpty2 (wartość) ). Będzie to działać dla wartości null; Nieokreślony; 0; „”; „”; false
RationalRabbit
6
return val || 'Handle empty variable'

jest naprawdę fajnym i czystym sposobem radzenia sobie z nim w wielu miejscach, można go również używać do przypisywania zmiennych

const res = val || 'default value'
cubefox
źródło
Wiele miejsc, ale nie wtedy, gdy domyślnym jest truei starasz się dostarczyć lub zwróci valz false.
Molomby
@Molomby to bardzo specyficzny przypadek na krawędzi, ale nawet z tym łatwo sobie const res = falsyValue ? true : falsyValue
poradzić
5

Jeśli zmienna nie została zadeklarowana, nie będzie możliwe sprawdzenie niezdefiniowanej za pomocą funkcji, ponieważ pojawi się błąd.

if (foo) {}
function (bar) {}(foo)

Oba wygenerują błąd, jeśli foo nie zostanie zadeklarowane.

Jeśli chcesz sprawdzić, czy zmienna została zadeklarowana, możesz użyć

typeof foo != "undefined"

jeśli chcesz sprawdzić, czy foo zostało zadeklarowane i ma wartość, której możesz użyć

if (typeof foo != "undefined" && foo) {
    //code here
}
herostwist
źródło
5

Aby sprawdzić wartość domyślną

function typeOfVar (obj) {
      return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
function isVariableHaveDefaltVal(variable) {
    if ( typeof(variable) === 'string' ) {  // number, boolean, string, object 
        console.log(' Any data Between single/double Quotes is treated as String ');        
        return (variable.trim().length === 0) ? true : false;
    }else if ( typeof(variable) === 'boolean' ) {
      console.log('boolean value with default value \'false\'');
        return (variable === false) ? true : false;
    }else if ( typeof(variable) === 'undefined' ) {
        console.log('EX: var a; variable is created, but has the default value of undefined.'); 
        return true;
    }else if ( typeof(variable) === 'number' ) { 
        console.log('number : '+variable);
        return (variable === 0 ) ? true : false;
    }else if ( typeof(variable) === 'object' ) {
   //   -----Object-----
        if (typeOfVar(variable) === 'array' && variable.length === 0) {
            console.log('\t Object Array with length = ' + [].length); // Object.keys(variable)
            return true;
        }else if (typeOfVar(variable) === 'string' && variable.length === 0 ) {
            console.log('\t Object String with length = ' + variable.length);
            return true;
        }else if (typeOfVar(variable) === 'boolean' ) {
            console.log('\t Object Boolean = ' + variable);
            return (variable === false) ? true : false;
        }else if (typeOfVar(variable) === 'number' ) {
            console.log('\t Object Number = ' + variable);
            return (variable === 0 ) ? true : false;
        }else if (typeOfVar(variable) === 'regexp' && variable.source.trim().length === 0 ) {
       console.log('\t Object Regular Expression : ');
        return true;
        }else if (variable === null) {
       console.log('\t Object null value');
        return true;
        }
    }
    return false;
}
var str = "A Basket For Every Occasion";
str = str.replace(/\s/g, "-");
//The "g" flag in the regex will cause all spaces to get replaced.

sprawdź Wynik:

isVariableHaveDefaltVal(' '); // string          
isVariableHaveDefaltVal(false); // boolean       
var a;           
isVariableHaveDefaltVal(a);               
isVariableHaveDefaltVal(0); // number             
isVariableHaveDefaltVal(parseInt('')); // NAN isNAN(' '); - true         
isVariableHaveDefaltVal(null);              
isVariableHaveDefaltVal([]);               
isVariableHaveDefaltVal(/ /);              
isVariableHaveDefaltVal(new Object(''));               
isVariableHaveDefaltVal(new Object(false));            
isVariableHaveDefaltVal(new Object(0)); 
typeOfVar( function() {} );

Użyłem funkcji @Vix (), aby sprawdzić obiekt tego typu.

za pomocą instansof «

var prototypes_or_Literals = function (obj) {
    switch (typeof(obj)) {
        // object prototypes
        case 'object':
            if (obj instanceof Array)
                return '[object Array]';
            else if (obj instanceof Date)
                return '[object Date]';
            else if (obj instanceof RegExp)
                return '[object regexp]';
            else if (obj instanceof String)
                return '[object String]';
            else if (obj instanceof Number)
                return '[object Number]';

            else
                return 'object';
        // object literals
        default:
            return typeof(obj);
    }   
};
output test «
prototypes_or_Literals( '' ) // "string"
prototypes_or_Literals( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]"        
Yash
źródło
Operatorzy porównania sprawdzają == [Dane]. === [Dane, typ obiektu] Numery JS są zawsze przechowywane jako liczby zmiennoprzecinkowe podwójnej precyzji, zgodnie z międzynarodowym standardem IEEE 754. // Number Type [int, float literals ] var int = 77; var float = 77.7; console.log( int.toFixed(10) + '\t' + float.toFixed(10) ); // Object Type var number = new Number( 77 ); if( int != float ) console.log('Data Not Equal'); if( int == number && int !== number ) console.log('Data is Equal & Types vary');
Yash
5
function isEmpty(obj) {
    if (typeof obj == 'number') return false;
    else if (typeof obj == 'string') return obj.length == 0;
    else if (Array.isArray(obj)) return obj.length == 0;
    else if (typeof obj == 'object') return obj == null || Object.keys(obj).length == 0;
    else if (typeof obj == 'boolean') return false;
    else return !obj;
}

W ES6 z wykończeniem do obsługi ciągów białych znaków:

const isEmpty = value => {
    if (typeof value === 'number') return false
    else if (typeof value === 'string') return value.trim().length === 0
    else if (Array.isArray(value)) return value.length === 0
    else if (typeof value === 'object') return value == null || Object.keys(value).length === 0
    else if (typeof value === 'boolean') return false
    else return !value
}
jales cardoso
źródło
1
świetna funkcja, dziękuję! obsługuje każdy rodzaj wartości - liczby są pomijane we wszystkich innych rozwiązaniach!
Fabian von Ellerts
1
@FabianvonEllerts Nie próbuj edytować dodatkowego kodu w odpowiedzi innej osoby. Opublikuj jako własną odpowiedź, jako komentarz pod odpowiedzią lub poproś w komentarzu, aby sami zaktualizowali odpowiedź.
TylerH,
5

Może się przydać.

Wszystkie wartości w tablicy reprezentują to, czym chcesz być (null, undefined lub inne rzeczy) i wyszukujesz w niej to, co chcesz.

var variablesWhatILookFor = [null, undefined, ''];
variablesWhatILookFor.indexOf(document.DocumentNumberLabel) > -1
ddagsan
źródło
2
czy mógłbyś wyjaśnić? co się tam dzieje
JoshKisb
Tablica zawiera pewną zmienną, która została przyjęta jako pusta.
ddagsan,
@JoshKisb wszystkie wartości w tablicy reprezentują to, czym chcesz być (null, niezdefiniowany lub inne rzeczy) i wyszukujesz w nim to, co chcesz.
ddagsan
1
@ddagsan Chociaż JoshKisb może docenić twoją odpowiedź, powinieneś umieścić swoje wyjaśnienie w swojej odpowiedzi, a nie w komentarzach
Nick
4

Jeśli używasz TypeScripti nie chcesz uwzględniać „wartości, są false oto rozwiązanie dla Ciebie:

Pierwszy: import { isNullOrUndefined } from 'util';

Następnie: isNullOrUndefined(this.yourVariableName)

Uwaga: jak wspomniano poniżej, to jest już przestarzałe, użyj value === undefined || value === nullzamiast tego. ref .

Czarnobrody
źródło
2
Myślałem, że to fajne, więc początkowo nie głosowałem, ale jest to rzecz przestarzała z Node.js. Plik definicji typów mówi:/** @deprecated since v4.0.0 - use "value === null || value === undefined" instead. */
atomictom
@atomictom Myślałem, że to typescriptcoś. Czy możesz podać link do jego dokumentacji?
BlackBeard
Tutaj: nodejs.org/api/util.html#util_util_isnullorundefined_object . Także: „Myślałem, że to było fajne, więc początkowo głosowałem ”, że powinienem przeczytać :)
atomictom
Dlaczego ta przestarzała przydatna prosta rzecz taka jak ta? geeeeee.
ticktock
3

Próżnia

Nie polecam próbować definiować ani używać funkcji, która oblicza, czy jakaś wartość na całym świecie jest pusta. Co to tak naprawdę znaczy być „pustym”? Jeśli tak let human = { name: 'bob', stomach: 'empty' }, czy powinienem isEmpty(human)wrócić true? Jeśli tak let reg = new RegExp('');, czy powinienem isEmpty(reg)wrócić true? Co z isEmpty([ null, null, null, null ])- ta lista zawiera tylko pustkę, więc czy sama lista jest pusta? Chcę przedstawić tutaj kilka uwag na temat „próżności” (słowo celowo niejasne, aby uniknąć wcześniejszych skojarzeń) w javascript - i chcę argumentować, że „próżności” w wartościach javascript nigdy nie należy traktować ogólnie.


Prawdomówność / fałsz

Aby zdecydować, w jaki sposób określić „próżność” wartości, musimy uwzględnić wbudowane, javascriptowe nieodłączne poczucie, czy wartości są „prawdą”, czy „fałszem”. Oczywiście nulli undefinedoba są „falsy”. Mniej naturalnie liczba 0(i żadna inna liczba oprócz NaN) jest również „fałszem”. ''Przynajmniej naturalnie: jest fałszem, ale []i {}(i new Set(), i new Map()) są prawdomówne - chociaż wszystkie wydają się równie próżne!


Null vs Undefined

Trwa także dyskusja na temat nullvs undefined- czy naprawdę potrzebujemy obu, aby wyrazić pustkę w naszych programach? Osobiście unikam, aby litery u, n, d, e, f, i, n, e, d pojawiały się w moim kodzie w tej kolejności. Zawsze używam nulldo oznaczenia „próżności”. Ponownie, choć musimy pomieścić Javascript w przyrodzone poczucie jak nulli undefinedróżnią się:

  • Próba uzyskania dostępu do nieistniejącej właściwości daje undefined
  • Pominięcie parametru podczas wywoływania funkcji powoduje otrzymanie tego parametru undefined:

let f = a => a;
console.log(f('hi'));
console.log(f());

  • Parametry z wartościami domyślnymi otrzymują wartość domyślną tylko wtedy undefined, gdy są podane , a nie null:

let f = (v='hello') => v;
console.log(f(null));
console.log(f(undefined));


Nieogólna próżnia

Uważam, że pustki nigdy nie powinny być traktowane w sposób ogólny. Zamiast tego powinniśmy zawsze dokładać starań, aby uzyskać więcej informacji o naszych danych przed ustaleniem, czy są one puste - robię to głównie poprzez sprawdzenie, z jakim typem danych mam do czynienia:

let isType = (value, Cls) => {
  try {
    return Object.getPrototypeOf(value).constructor === Cls;
  } catch(err) {
    return false;
  }
};

Zauważ, że ta funkcja ignoruje polimorfizm - oczekuje valuesię, że będzie to bezpośrednia instancja Cls, a nie instancja podklasy Cls. Unikam instanceofz dwóch głównych powodów:

  • ([] instanceof Object) === true („Tablica to obiekt”)
  • ('' instanceof String) === false („Ciąg nie jest ciągiem”)

Zauważ, że Object.getPrototypeOfjest używany, aby uniknąć przypadku takiego jak let v = { constructor: String };. isTypeFunkcja nadal zwraca poprawnie dla isType(v, String)(fałsz) iisType(v, Object) (prawda).

Ogólnie polecam korzystanie z tej isTypefunkcji wraz z następującymi wskazówkami:

  • Zminimalizuj ilość wartości przetwarzania kodu nieznanego typu. Np. let v = JSON.parse(someRawValue);Nasza vzmienna jest teraz nieznanego typu. Jak najwcześniej powinniśmy ograniczyć nasze możliwości. Najlepszym sposobem na to może być wymaganie określonego typu: np. if (!isType(v, Array)) throw new Error('Expected Array');- jest to naprawdę szybki i ekspresyjny sposób na usunięcie ogólnej natury vi zapewnienie, że zawsze będzie Array. Czasami jednak musimy pozwolić vna bycie wielu typów. W takich przypadkach vjak najwcześniej powinniśmy utworzyć bloki kodu, które nie są już ogólne.

if (isType(v, String)) {
  /* v isn't generic in this block - It's a String! */
} else if (isType(v, Number)) {
  /* v isn't generic in this block - It's a Number! */
} else if (isType(v, Array)) {
  /* v isn't generic in this block - it's an Array! */
} else {
  throw new Error('Expected String, Number, or Array');
}

  • Zawsze używaj „białych list” do walidacji. Jeśli potrzebujesz, aby wartością była np. Ciąg, Liczba lub Tablica, sprawdź te 3 „białe” możliwości i wyrzuć Błąd, jeśli żadna z 3 nie jest spełniona. Powinniśmy być w stanie zobaczyć, że sprawdzanie dla „czarnych” możliwości nie jest bardzo przydatne: Say piszemy if (v === null) throw new Error('Null value rejected');- to jest wielki dla zapewnienia, że nullwartości nie zrobić to przez, ale jeśli to jest wartość nie zrobić to przez, wciąż wiemy mało cokolwiek na ten temat. Wartość, vktóra przejdzie kontrolę zerową, jest nadal BARDZO ogólna - to nic innegonull ! Czarne listy prawie nie rozpraszają ogólności.
  • O ile wartość nie jest null, nigdy nie uważaj „wartości pustej”. Zamiast tego rozważ „X, który jest pusty”. Zasadniczo nigdy nie rozważaj robienia czegoś podobnego if (isEmpty(val)) { /* ... */ }- bez względu na to, jak ta isEmptyfunkcja jest zaimplementowana (nie chcę wiedzieć ...), to nie ma znaczenia! I to jest zbyt ogólne! Wakat należy obliczać tylko przy znajomości valrodzaju. Kontrole próżni powinny wyglądać następująco:

    • „Ciąg bez znaków”: if (isType(val, String) && val.length === 0) ...
    • „Obiekt z 0 rekwizytami”: if (isType(val, Object) && Object.entries(val).length === 0) ...
    • „Liczba równa lub mniejsza niż zero”: if (isType(val, Number) && val <= 0) ...
    • „Tablica bez przedmiotów”: if (isType(val, Array) && val.length === 0) ...

    • Jedynym wyjątkiem jest sytuacja, gdy nulljest używany do oznaczenia określonej funkcjonalności. W tym przypadku sensowne jest powiedzenie: „Pusta wartość”:if (val === null) ...

Gershom
źródło
Widzę, że zastanowiłeś się nad tym:>
Rui Marques
3

Spróbuj z inną logiką . Możesz użyć poniższego kodu do sprawdzenia wszystkich czterech (4) warunków sprawdzania poprawności, takich jak: nie jest pusty, nie jest pusty, nie jest niezdefiniowany i nie zero używa tylko tego kodu (! (! (Zmienna))) w javascript i jquery.

function myFunction() {
    var data;  //The Values can be like as null, blank, undefined, zero you can test

    if(!(!(data)))
    {
        alert("data "+data);
    } 
    else 
    {
        alert("data is "+data);
    }
}
Ravikant
źródło
3

Spójrz na nowego operatora koalescencyjnego ECMAScript Nullish

Możesz myśleć o tej funkcji - ??operatorze - jako o „powrocie” do wartości domyślnej w przypadku nulllub undefined.

let x = foo ?? bar();

Ponownie powyższy kod jest równoważny z poniższym.

let x = (foo !== null && foo !== undefined) ? foo : bar();
Daniel Eduardo Delgado Diaz
źródło
2
function isEmpty(val){
    return !val;
}

ale to rozwiązanie jest przeprojektowane, jeśli nie chcesz później modyfikować funkcji dla potrzeb modelu biznesowego, wtedy łatwiej jest użyć jej bezpośrednio w kodzie:

if(!val)...
Luca C.
źródło
2
var myNewValue = myObject && myObject.child && myObject.child.myValue;

To nigdy nie spowoduje błędu. Jeśli myObject , child lub myValue ma wartość NULL, to myNewValue będzie miało wartość NULL. Błędy nie będą zgłaszane

Keith Blanchard
źródło
2

Dla wszystkich, którzy przychodzą tutaj z podobnym pytaniem, następujące działa świetnie i mam je w mojej bibliotece w ostatnich latach:

(function(g3, $, window, document, undefined){
   g3.utils = g3.utils || {};
/********************************Function type()********************************
* Returns a lowercase string representation of an object's constructor.
* @module {g3.utils}
* @function {g3.utils.type}
* @public
* @param {Type} 'obj' is any type native, host or custom.
* @return {String} Returns a lowercase string representing the object's 
* constructor which is different from word 'object' if they are not custom.
* @reference http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
* http://stackoverflow.com/questions/3215046/differentiating-between-arrays-and-hashes-in-javascript
* http://javascript.info/tutorial/type-detection
*******************************************************************************/
g3.utils.type = function (obj){
   if(obj === null)
      return 'null';
   else if(typeof obj === 'undefined')
      return 'undefined';
   return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
};
}(window.g3 = window.g3 || {}, jQuery, window, document));
centurian
źródło
2

Jeśli chcesz uniknąć spełnienia warunku, jeśli wartość jest dowolna z poniższych, zgodnie z odpowiedzią jAndy :

  • zero
  • nieokreślony
  • NaN
  • pusta struna ("")
  • 0
  • fałszywe

Jednym z możliwych rozwiązań, które mogą uniknąć uzyskania prawdziwych wartości, są następujące:

function isUsable(valueToCheck) {
    if (valueToCheck === 0     || // Avoid returning false if the value is 0.
        valueToCheck === ''    || // Avoid returning false if the value is an empty string.
        valueToCheck === false || // Avoid returning false if the value is false.
        valueToCheck)             // Returns true if it isn't null, undefined, or NaN.
    {
        return true;
    } else {
        return false;
    }
}

Byłby używany w następujący sposób:

if (isUsable(x)) {
    // It is usable!
}
// Make sure to avoid placing the logical NOT operator before the parameter (isUsable(!x)) and instead, use it before the function, to check the returned value.
if (!isUsable(x)) {
    // It is NOT usable!
}

Oprócz tych scenariuszy warto zwrócić wartość false, jeśli obiekt lub tablica jest pusta:

  • Obiekt: {} (przy użyciu ECMA 7+ )
  • Tablica: [] (przy użyciu ECMA 5+ )

Poradziłbyś sobie w ten sposób:

function isEmptyObject(valueToCheck) {
    if(typeof valueToCheck === 'object' && !Object.keys(valueToCheck).length){
        // Object is empty!
        return true;
    } else {
        // Object is not empty!
        return false;
    }
}

function isEmptyArray(valueToCheck) {
    if(Array.isArray(valueToCheck) && !valueToCheck.length) {
        // Array is empty!
        return true;
    } else {
        // Array is not empty!
        return false;
    }
}

Jeśli chcesz sprawdzić wszystkie ciągi białych znaków („”), możesz wykonać następujące czynności:

function isAllWhitespace(){
    if (valueToCheck.match(/^ *$/) !== null) {
        // Is all whitespaces!
        return true;
    } else {
        // Is not all whitespaces!
        return false;
    }
}

Uwaga: hasOwnPropertyzwraca true dla pustych ciągów, 0, false, NaN, null i undefined, jeśli zmienna została zadeklarowana jako dowolna z nich, więc może nie być najlepszym wyborem. Funkcja może zostać zmodyfikowana w celu użycia jej w celu pokazania, że ​​została zadeklarowana, ale nie jest użyteczna.

yaharga
źródło
2

Kod na GitHub

const isEmpty = value => (
  (!value && value !== 0 && value !== false)
  || (Array.isArray(value) && value.length === 0)
  || (isObject(value) && Object.keys(value).length === 0)
  || (typeof value.size === 'number' && value.size === 0)

  // `WeekMap.length` is supposed to exist!?
  || (typeof value.length === 'number'
      && typeof value !== 'function' && value.length === 0)
);

// Source: https://levelup.gitconnected.com/javascript-check-if-a-variable-is-an-object-and-nothing-else-not-an-array-a-set-etc-a3987ea08fd7
const isObject = value =>
  Object.prototype.toString.call(value) === '[object Object]';

Testy biednych ludzi 😁

const test = () => {
  const run = (label, values, expected) => {
    const length = values.length;
    console.group(`${label} (${length} tests)`);
    values.map((v, i) => {
      console.assert(isEmpty(v) === expected, `${i}: ${v}`);
    });
    console.groupEnd();
  };

  const empty = [
    null, undefined, NaN, '', {}, [],
    new Set(), new Set([]), new Map(), new Map([]),
  ];
  const notEmpty = [
    ' ', 'a', 0, 1, -1, false, true, {a: 1}, [0],
    new Set([0]), new Map([['a', 1]]),
    new WeakMap().set({}, 1),
    new Date(), /a/, new RegExp(), () => {},
  ];
  const shouldBeEmpty = [
    {undefined: undefined}, new Map([[]]),
  ];

  run('EMPTY', empty, true);
  run('NOT EMPTY', notEmpty, false);
  run('SHOULD BE EMPTY', shouldBeEmpty, true);
};

Wyniki testów:

EMPTY (10 tests)
NOT EMPTY (16 tests)
SHOULD BE EMPTY (2 tests)
  Assertion failed: 0: [object Object]
  Assertion failed: 1: [object Map]
Pascal Polleunus
źródło
świetna funkcja, wszystkie inne odpowiedzi tutaj zawierały wiele problemów, które wydaje się rozwiązać, po prostu szkoda, że ​​nie znalazłem, zanim napisałem własną: p pomyślałem, że mógłbyś rzucić okiem na moją pracę stackoverflow.com/ pytania / 5515310 /… obie nasze funkcje wydają się mieć dokładnie takie same wyniki, ale trochę zmniejszyłem kod. Daj mi znać, jeśli coś przeoczyłem.
Sean Bannister
👍 Czy próbowałeś moich „testów ubogich”? Myślę, że w końcu dodałem więcej testów w funkcji dla specjalnych przypadków, takich jak Map, WeakMap, a może także Date, RegExp. Jesteś pewien swojej value.constructor === Object? Sprawdź to .
Pascal Polleunus
Tak, uruchomiłem twoje testy, dzięki za te, obie nasze funkcje zwracają te same wyniki z obydwoma naszymi testami. Zastanawiam się, czy brakuje mi czegoś poza tymi testami. Uważam, że value.constructor === Objectjest w porządku, w javascript JEŻELI instrukcje OR mają kolejność wykonywania, dzięki czemu instrukcja OR będzie wykonywana tylko wtedy, gdy poprzednie nie zwróciło PRAWDA, a my już sprawdziliśmy Null. W rzeczywistości jedynym celem tej ostatniej instrukcji OR jest wykrycie {}i upewnienie się, że nie zwraca PRAWDA dla rzeczy, których nie powinna.
Sean Bannister,
1

To sprawdzi, czy zmienna nieokreślonego zagnieżdżenia jest niezdefiniowana

function Undef(str) 
{
  var ary = str.split('.');
  var w = window;
  for (i in ary) {
    try      { if (typeof(w = w[ary[i]]) === "undefined") return true; }
    catch(e) { return true; }
  }
  return false;
}

if (!Undef("google.translate.TranslateElement")) {

Powyższe sprawdza, czy istnieje funkcja tłumaczenia Google TranslateElement. Jest to równoważne z:

if (!(typeof google === "undefined" 
 || typeof google.translate === "undefined" 
 || typeof google.translate.TranslateElement === "undefined")) {
rickdog
źródło
1

Opcjonalny operator łączenia łańcuchowego umożliwia uproszczenie dostępu do wartości przez połączone obiekty, gdy możliwe jest, że odwołanie lub funkcja mogą być niezdefiniowane lub mieć wartość zerową.

let customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls" // detailed address is unknown
  }
};
let customerCity = customer.details?.address?.city;

Zerowy operator koalescencyjny może być użyty po opcjonalnym łańcuchowaniu w celu zbudowania wartości domyślnej, gdy nie zostanie znaleziony:

let customer = {
  name: "Carl",
  details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city
Sunny Sultan
źródło
1
function notEmpty(value){
  return (typeof value !== 'undefined' && value.trim().length);
}

sprawdzi także białe spacje ('') wraz z następującymi:

  • null, undefined, NaN, empty, string (""), 0, false
Hassan Ali Shahzad
źródło
0

Myślę, że za pomocą? operator jest nieco czystszy.

var ? function_if_exists() : function_if_doesnt_exist();
Pedro Pereira
źródło