Существует ли стандартная функция для проверки нулевых, неопределенных или пустых переменных в JavaScript?

2262

Есть ли универсальная функция JavaScript, которая проверяет, что переменная имеет значение и гарантирует, что это не так undefinedили нет null? У меня есть этот код, но я не уверен, что он охватывает все случаи:

function isEmpty(val){
    return (val === undefined || val == null || val.length <= 0) ? true : false;
}
Alex
источник
78
Протип, никогда не делай (truthy statement) ? true : false;. Просто делай (truthy statement);.
Дэвид Баукум
5
@GeorgeJempty не является дуплом, так как другой ответ спрашивает, в частности, о строках , а этот - о переменных .
Madbreaks
2
Любой правильный ответ на этот вопрос полностью зависит от того, как вы определяете «пусто».
Madbreaks
3
@Jay Это не повредит ничего, кроме выполнения вашего кода. Это просто слишком многословно. Вы не сказали бы: «Ты голоден, это правда?» Вы просто «Вы голодны»? Так в коде просто скажите if (hungry) …вместо if (hungry === true) …. Как и все вещи, написанные таким образом, это просто вопрос вкуса. Более конкретно к примеру, предоставленному ОП, он еще более многословно говорит: «Если это правда, то правда, если нет, то ложь». Но если это правда, то это уже правда. И, если это ложно, это уже ложно. Это все равно что сказать: «Если ты голоден, значит, есть, а если нет, то нет».
Дэвид Баукум

Ответы:

4383

Вы можете просто проверить , если переменная имеет truthyзначение или нет. Это значит

if( value ) {
}

будет вычисляться , trueесли valueэто не :

  • значение NULL
  • не определено
  • NaN
  • пустой строкой ("")
  • 0
  • ложный

Приведенный выше список представляет все возможные falsyзначения в ECMA- / Javascript. Найдите это в спецификации в ToBooleanразделе.

Кроме того, если вы не знаете , существует ли переменная (то есть, если она была объявлена ), вам следует проверить с typeofоператором. Например

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

Если вы можете быть уверены, что переменная объявлена ​​как минимум, вам следует непосредственно проверить, имеет ли она truthyзначение, как показано выше.

Далее читайте: http://typeofnan.blogspot.com/2011/01/typeof-is-fast.html

JANDY
источник
110
Что, если значение является ложным логическим значением, которое было предназначено. Иногда вы хотите задать значение по умолчанию, если значение отсутствует, которое не будет работать, если было передано ложное логическое значение.
TruMan1
100
@ TruMan1: в таком случае (когда ваша логика требует проверки) вы должны идти как if( value || value === false ). То же самое относится ко всем ложным значениям , мы должны проверить их явно.
Джэнди
28
За исключением случаев, когда значение является массивом. Интерпретация truthyможет вводить в заблуждение. В этом случае мы должны проверять value.length != 0непустой массив.
пользователь
12
Просто хочу добавить , что если вы чувствуете , что ifконструкция является синтаксический слишком тяжелой, вы можете использовать тройной оператор, например , так: var result = undefined ? "truthy" : "falsy". Или если вы просто хотите , чтобы принуждать к логическому значению, используйте !!оператор, например !!1 // true, !!null // false.
KFL
7
Также обратите внимание, что это не будет проверять строки, которые содержат только пробельные символы.
Кристоф Русси
222

Подробный метод, чтобы проверить, является ли значение неопределенным или нулевым:

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

Вы также можете использовать ==оператор, но это предполагает, что он знает все правила :

return value == null; // also returns true if value is undefined
Салман А
источник
33
Проверка только nullили undefinedможет быть сделано следующим образом: if (value == null). Имейте в виду ==оператора, который принуждает. Если вы проверите, как это if (value === null || value === undefined), вы забыли / не знаете, как принуждает Javascript. webreflection.blogspot.nl/2010/10/…
Кристиан
32
@ChristiaanWesterbeek: ваша точка зрения arg == nullдает те же результаты, что и arg === undefined || arg === null. Однако я считаю последний пример более читабельным.
Салман А
10
arg == nullдовольно часто встречается в моем опыте.
Брайан Даунинг
8
return value === (void 0)К undefinedсожалению, безопаснее, чем тестирование, которое вполне может быть допустимой переменной в области видимости.
x0n
4
@Sharky Существует разница между неопределенной переменной и необъявленной переменной: lucybain.com/blog/2014/null-undefined-undeclared
Christiaan Westerbeek
80
function isEmpty(value){
  return (value == null || value.length === 0);
}

Это вернет истину для

undefined  // Because undefined == null

null

[]

""

и функции с нулевым аргументом, поскольку функция length- это число объявленных параметров, которые она принимает.

Чтобы запретить последнюю категорию, вы можете просто проверить наличие пустых строк

function isEmpty(value){
  return (value == null || value === '');
}
Майк Самуэль
источник
7
undefined == nullноundefined !== null
Ян Бойд
2
@IanBoyd, потому что вы сравниваете == с ===. это означает, что undefined == null (true) undefined! = null (false) undefined === null (false) undefined! == null (true) было бы лучше дать немного больше информации, чтобы быть полезным и подтолкнуть людей в правильном направлении. Моз док о разнице developer.mozilla.org/en-US/docs/Web/JavaScript/…
Кори Янг
43

Это самая безопасная проверка, и я не видел, чтобы она была опубликована здесь в точности так:

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

Он будет охватывать случаи, когда значение никогда не определялось, а также любой из них:

  • значение NULL
  • undefined (значение undefined не совпадает с параметром, который никогда не определялся)
  • 0
  • "" (пустой строкой)
  • ложный
  • NaN

Отредактировано: изменено на строгое равенство (! ==), потому что сейчас это норма;)

Guya
источник
10
Я не отрицал, но в отношении строгого сравнения на равенство, общее правило таково, что если вам не нужно неявное преобразование типов, следует использовать строгое сравнение.
J.Steve
2
Спасибо за ваш комментарий Стив. Это общее правило просто отлично. Я просто ожидаю, что люди поймут, почему они используют один или другой. Каждый раз, как вы выглядите, ppl будет рад проповедовать о том, что «всегда всегда используйте строгий» - как будто это самая важная вещь в Javascript. Я видел слишком много случаев, таких как if (val! == null), которые явно приводят к нежелательному результату. Приятно сказать, что, когда сомневаешься - пользуйся строгим, но лучше не сомневаться.
Гуя
6
Я думаю, суть в том, что мы ожидаем, что typeofоператор вернет строку, поэтому использование строгой проверки на равенство технически более точно, более конкретно и быстрее. Так что на самом деле, нет никаких оснований для использования свободного сравнения, а не наоборот. Также val !== nullотлично действует во многих случаях - я делаю это все время. Я согласен с вашим аргументом о несоответствии, но я думаю, что это плохой пример, чтобы сделать это. Не пытаюсь тебя троллить.
Брайан Даунинг
Спасибо за ваш комментарий Брайан, Вы используете val! == null, потому что знаете, что делаете. Новичок захочет иметь запасной вариант, когда val ложен. Но val никогда не будет нулевым, он будет неопределенным. Если бы только он не послушал этот совет «всегда всегда используй строгий», у него было бы меньше ошибок. Я видел, как это происходит в производственном коде. typeof всегда возвращает строку, а скорость diff будет избыточной. Таким образом, единственным аргументом для использования строгого в вышеуказанном случае является последовательность. Я сказал: «Нет необходимости в строгом равенстве». Это не значит, что вы не можете, если хотите, или если это делает ваш код более согласованным.
Гуя
28

Вам может пригодиться следующая функция:

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

Или в ES7 (прокомментируйте, если дальнейшие улучшения)

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

  return type.toLowerCase();
}

Результаты:

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

«Обратите внимание, что оператор связывания (: :) не является ни частью ES2016 (ES7), ни какой-либо более поздней редакцией стандарта ECMAScript вообще. В настоящее время он является предложением стадии 0 (strawman) для введения в язык». - Саймон Кьельберг. Автор хотел бы добавить свою поддержку этого прекрасного предложения получить королевское вознесение.

Vix
источник
+1 полезно знать объект типа 'regexp' , 'array' и 'function'
Yash
@ Vix, почему версия ES7 лучше?
GollyJer
Нет, экспериментировал с более читаемыми способами выражения той же функциональности, используя: деструктурирование присваивания, оператор связывания.
Vix
2
Обратите внимание, что оператор связывания ( ::) не является частью ES2016 (ES7) или какой-либо более поздней редакции стандарта ECMAScript. В настоящее время это предложение стадии 0 (соломенный) для ознакомления с языком.
Саймон Кьеллберг
25

Первый ответ с лучшим рейтингом неверен. Если значение не определено, оно выдаст исключение в современных браузерах. Вы должны использовать:

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

или

if (typeof value  !== "undefined" && value)
krupar
источник
3
эээ ... я думаю, что это неправильно, как будто (значение) достаточно (за исключением пустых объектов / массивов). если значение равно «undefined», признание «if» не пройдет.
Оскар Шура
3
Это объединяет переменные, которые не определены (которые генерируют ReferenceError при оценке), которые отличаются от переменных со undefinedзначением.
Qantas 94 Heavy
2
Я получил ту же ошибку здесь. if (x), if (! x), if (!! x) выдает ошибку, если x не определен.
Shaosh
if(value === 0) gameOver(); ;)
Madbreaks
Этот ответ также неверен, потому что он возвращает false, когда valueравен нулю, а это не то, что ищет опера.
Madbreaks
17

Это условие проверки

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

это все, что тебе нужно.

JerryP
источник
Я предполагаю, что это всего лишь фрагмент. Но ifуже делает ложную проверку, которая просто конвертируется в логическое значение. Ловит ли он какие-либо случаи, которые нормальная if(foo)не ловит?
Даан ван Хюлст
1
Это идеально подходит для случаев, когда вам нужно что-то встроенное, например, мне нужен атрибут реагирования (называемый активным), который имеет значение true, когда строка не пустая - оператор if будет излишним, поэтому я могу просто использоватьactive={!!foo}
Ben Kolya Mansley
16

! проверьте наличие пустых строк (""), нулевых, неопределенных, ложных и числа 0 и NaN. Скажем, если строка пуста, var name = ""то console.log(!name)возвращается true.

function isEmpty(val){
  return !val;
}

эта функция возвращает истину , если вал является пустым, пустым, не определено, ложь, число 0 или NaN .

ИЛИ

В зависимости от вашей проблемной области вы можете просто использовать как !valили !!val.

Arif
источник
Это на самом деле не говорит, является ли переменная пустой, поскольку false и 0 могут быть допустимыми значениями и не представлять собой пустое значение. Ценность наличия функции isEmpty состояла бы в том, чтобы гарантировать, что ожидаемые значения, которые являются пустыми, возвращают true. по моему мнению, null, undefined, NaN и пустая строка являются значениями, которые имеют смысл как пустые.
Кори Янг
9
Зачем использовать, isEmpty(val)если вы могли бы просто сделать !val?
Аллен Линаток
Это тебе решать. Вы можете использовать его для повышения читабельности. В противном случае, если вы считаете, что команда, в которой вы работаете, является более продвинутым программистом, то вы можете использовать только !valили в !!valзависимости от вашей проблемной области.
Ариф
15

Решение мне очень нравится:

Давайте определим, что пустая переменная равна nullили undefined, или если она имеет длину, равна нулю, или, если это объект, у нее нет ключей:

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)
  )
}

Возвращает:

  • правда: undefined , null, "", [],{}
  • ложь: true , false, 1, 0, -1, "foo", [1, 2, 3],{ foo: 1 }
Александр Магро
источник
14

Вы немного переусердствовали. Чтобы проверить, что переменной не присвоено значение, вам нужно будет проверить только undefined и null.

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

Это предполагает 0, ""и объекты (даже пустой объект и массив) являются допустимыми «значениями».

tcooc
источник
10

Если вы предпочитаете простой javascript, попробуйте это:

  /**
   * 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;
  }

В противном случае, если вы уже используете подчеркивание или lodash, попробуйте:

_.isEmpty(value)
L3x
источник
3
Попробовал ваш код. Я получаю сообщение об ошибке в консоли, которое гласит: «Uncaught reference error: isArray () не определен». В противном случае было бы здорово, если бы это работало.
crmprogdev
11
По крайней мере, в случае с lodash _.isNil- это та функция, которую вы ищете, а не _.isEmpty. isNil документация , IsEmpty документация
Snixtor
Это потерпит неудачу, если значение логическое и имеет значение true.
kalyanbk
3
Обычный JavaScript не имеет isArrayили не isStringработает на window.
GFoley83
@ GFoley83 - Ты поймал меня! У меня есть причины не использовать Windows. Я на самом деле освещаю тему в главе, которая рассказывает об истории и прогрессе языков программирования. Более важной информацией, вероятно, будет обсуждение / код, демонстрирующий обработку монадических ошибок в моей книге «Изучите функциональное программирование на ходу». Ура!
13
9

Вот мое - возвращает true, если значение равно null, undefined и т. Д. Или пусто (т.е. содержит только пробелы):

function stringIsEmpty(value) {

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

}
DavidWainwright
источник
1
Я сделал тест на нескольких методах здесь. С проверкой неопределенности ваша функция работает отлично. Поэтому я использую if (typeof value! == 'undefined' &&! IsEmpty (value)) OR, если вы действительно хотите проверить наличие пустых значений, вы можете использовать if (typeof value === 'undefined' || IsEmpty2 (value) ). Это будет работать для нуля; Неопределенный; 0; ""; ""; false
RationalRabbit
6
return val || 'Handle empty variable'

это действительно хороший и чистый способ справиться с этим во многих местах, также может быть использован для назначения переменных

const res = val || 'default value'
cubefox
источник
Много мест , но не тогда , когда по умолчанию , trueи вы пытаетесь поставить или возвращать valиз false.
Моломби
@Molomby - это очень специфический крайний случай, но даже с этим легко справитьсяconst res = falsyValue ? true : falsyValue
cubefox
5

Если переменная не была объявлена, вы не сможете проверить неопределенность с помощью функции, потому что получите ошибку.

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

Оба сгенерируют ошибку, если foo не был объявлен.

Если вы хотите проверить, была ли объявлена ​​переменная, вы можете использовать

typeof foo != "undefined"

если вы хотите проверить, объявлен ли foo и имеет ли оно значение, которое вы можете использовать

if (typeof foo != "undefined" && foo) {
    //code here
}
herostwist
источник
5

Чтобы проверить значение по умолчанию

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.

Результат проверки:

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() {} );

Я использовал функцию @Vix () для проверки объекта какого типа.

используя 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]"        
Яши
источник
Операторы сравнения проверяют == [Данные]. === [Данные, тип объекта] Числа JS всегда хранятся как числа с плавающей запятой двойной точности, в соответствии с международным стандартом 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');
Яш
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;
}

В ES6 с отделкой для обработки пустых строк:

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
}
джейлс кардосо
источник
1
отличная функция, спасибо! обрабатывает каждый тип значения - числа опущены во всех других решениях!
Фабиан фон Эллертс
1
@FabianvonEllerts Пожалуйста, не пытайтесь редактировать дополнительный код в чужом ответе. Опубликуйте его как собственный ответ, как комментарий к ответу или попросите в комментарии, чтобы они сами обновили ответ.
TylerH
5

Это может быть полезно.

Все значения в массиве представляют собой то, кем вы хотите быть (ноль, неопределенное или другое), и вы ищете в нем то, что хотите.

var variablesWhatILookFor = [null, undefined, ''];
variablesWhatILookFor.indexOf(document.DocumentNumberLabel) > -1
ddagsan
источник
2
не могли бы вы объяснить, пожалуйста. что там происходит
JoshKisb
Массив содержит некоторую переменную, которую вы приняли за пустую.
ddagsan
@JoshKisb все значения в массиве представляют собой то, кем вы хотите быть (ноль, неопределенное или другое), и вы ищете в нем то, что хотите.
ddagsan
1
@ddagsan В то время как JoshKisb может оценить ваш ответ, вы должны поместить свое объяснение в свой ответ, а не в комментарии
Ник
4

Если вы используете TypeScriptи не хотите учитывать «ценности, которые есть false», то это решение для вас:

Первый: import { isNullOrUndefined } from 'util';

Затем: isNullOrUndefined(this.yourVariableName)

Обратите внимание: как уже упоминалось ниже, это устарело, используйте value === undefined || value === nullвместо этого. исх .

Бороды
источник
2
Я думал, что это круто, поэтому я изначально не голосовал, но это вещь Node.js, которая устарела. Тип файла определений гласит:/** @deprecated since v4.0.0 - use "value === null || value === undefined" instead. */
atomictom
@atomictom Я думал, что это typescriptвещь. Можете ли вы предоставить ссылку на его документацию?
BlackBeard
Здесь: nodejs.org/api/util.html#util_util_isnullorundefined_object . Кроме того: «Я думал, что это круто, поэтому я изначально проголосовал », что следует прочитать :)
atomictom
Почему бы отказаться от полезной простой вещи, как это? geeeeees.
тиканье
3

вырожденность

Я не рекомендую пытаться определить или использовать функцию, которая вычисляет, является ли какое-либо значение во всем мире пустым. Что на самом деле означает быть «пустым»? Если у меня есть let human = { name: 'bob', stomach: 'empty' }, должен isEmpty(human)вернуться true? Если у меня есть let reg = new RegExp('');, должен isEmpty(reg)вернуться true? Как насчет isEmpty([ null, null, null, null ])- этот список содержит только пустоту, поэтому сам список пуст? Я хочу выдвинуть здесь некоторые примечания о «пустотности» (намеренно неясное слово, чтобы избежать ранее существовавших ассоциаций) в javascript - и я хочу доказать, что «пустотность» в значениях javascript никогда не должна рассматриваться вообще.


Truthiness / Falsiness

Чтобы решить, как определить «пустоту» значений, нам нужно учесть встроенный в javascript внутренний смысл того, являются ли значения «правдивыми» или «ложными». Естественно nullи то undefinedи другое "фальшиво". Менее естественно, число 0(и никакое другое число кроме NaN) также не соответствует действительности. Наименее естественно: ''это ложь, но []и {}new Set(), и new Map()) правдивы - хотя все они кажутся одинаково пустыми!


Нулевой и неопределенный

Существует также некоторая дискуссия относительно nullvs undefined- действительно ли нам нужно и то, и другое, чтобы выразить пустоту в наших программах? Лично я избегаю, чтобы буквы u, n, d, e, f, i, n, e, d появлялись в моем коде в таком порядке. Я всегда использую nullдля обозначения "пустотности". Опять же, тем не менее, мы должны учесть присущие JavaScript особенности того, как nullи чем undefinedотличаются:

  • Попытка получить доступ к несуществующему свойству дает undefined
  • Пропуск параметра при вызове функции приводит к получению этого параметра undefined:

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

  • Параметры со значениями по умолчанию получают значение по умолчанию только тогда undefined, когда они заданы , а не null:

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


Неуниверсальная бессмысленность

Я считаю, что пустотность никогда не должна рассматриваться в общем виде. Вместо этого мы должны всегда иметь возможность получить больше информации о наших данных, прежде чем определять, являются ли они пустыми - я в основном делаю это, проверяя, с каким типом данных я имею дело:

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

Обратите внимание, что эта функция игнорирует полиморфизм - она valueдолжна быть прямым экземпляром Cls, а не экземпляром подкласса Cls. Я избегаю instanceofпо двум основным причинам:

  • ([] instanceof Object) === true («Массив - это объект»)
  • ('' instanceof String) === false («Строка не Строка»)

Обратите внимание , что Object.getPrototypeOfиспользуется , чтобы избежать случая , как функция по- прежнему возвращает правильно для (ложь), и (истина).let v = { constructor: String };isTypeisType(v, String)isType(v, Object)

В целом, я рекомендую использовать эту isTypeфункцию вместе с этими советами:

  • Минимизируйте количество значений обработки кода неизвестного типа. Например, let v = JSON.parse(someRawValue);наша vпеременная теперь неизвестного типа. Как можно раньше, мы должны ограничить наши возможности. Лучшим способом сделать это может быть требование определенного типа: например, if (!isType(v, Array)) throw new Error('Expected Array');это действительно быстрый и выразительный способ удалить общий характер vи убедиться, что он всегда есть Array. Однако иногда нам нужно разрешить vбыть нескольких типов. В этих случаях мы должны создавать блоки кода, гдеv больше не являются общими, как можно раньше:

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');
}

  • Всегда используйте «белые списки» для проверки. Если вам требуется, чтобы значением было, например, String, Number или Array, проверьте эти 3 «белые» возможности и выведите Error, если ни один из 3 не удовлетворен. Мы должны видеть, что проверка «черных» возможностей не очень полезна: скажем, мы пишем if (v === null) throw new Error('Null value rejected');- это отлично подходит для того, чтобы nullзначения не проходили, но если значение таки проходит, мы все равно вряд ли узнаем что-нибудь об этом. Значение, vкоторое проходит эту нулевую проверку, все еще ОЧЕНЬ универсально - это совсем не такnull ! Черные списки вряд ли рассеивают родственность.
  • Если значение не является null, никогда не считайте «пустым значением». Вместо этого рассмотрим «X, который является пустым». По сути, никогда if (isEmpty(val)) { /* ... */ }не думайте о том, чтобы делать что-то подобное - независимо от того, isEmptyкак реализована эта функция (я не хочу знать ...), это не имеет смысла! И это слишком общий характер! Неопределенность следует рассчитывать только со знанием valтипа России. Проверки пустотности должны выглядеть так:

    • «Строка без символов»: if (isType(val, String) && val.length === 0) ...
    • «Объект с 0 реквизитами»: if (isType(val, Object) && Object.entries(val).length === 0) ...
    • «Число, равное или меньшее нуля»: if (isType(val, Number) && val <= 0) ...
    • «Массив без элементов»: if (isType(val, Array) && val.length === 0) ...

    • Единственное исключение - когда nullиспользуется для обозначения определенных функций. В этом случае имеет смысл сказать: «пустое значение»:if (val === null) ...

Гирсам
источник
Я вижу, вы подумали об этом:>
Руи Маркес
3

Попробуйте с другой логикой . Вы можете использовать приведенный ниже код для проверки всех четырех (4) условий для проверки, например, не ноль, не пустой, не неопределенный и не ноль, используйте только этот код (! (! (Variable))) только в javascript и 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
источник
3

Взгляните на новый оператор объединения ECMAScript Nullish

Вы можете думать об этой функции - ??операторе - как о способе «возврата» к значению по умолчанию при работе с nullили undefined.

let x = foo ?? bar();

Опять же, приведенный выше код эквивалентен следующему.

let x = (foo !== null && foo !== undefined) ? foo : bar();
Даниэль Эдуардо Дельгадо Диас
источник
2
function isEmpty(val){
    return !val;
}

но это решение перегружено, если вы не хотите позже модифицировать функцию для нужд бизнес-модели, то лучше использовать ее непосредственно в коде:

if(!val)...
Лука С.
источник
2
var myNewValue = myObject && myObject.child && myObject.child.myValue;

Это никогда не выдаст ошибку. Если myObject , child или myValue равно нулю, то myNewValue будет равно нулю. Ошибки не будут выброшены

Кит Бланшар
источник
2

Для всех, кто приезжает сюда для того, чтобы иметь подобный вопрос, следующие прекрасно работают, и у меня есть это в моей библиотеке в последние годы:

(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
источник
2

Если вы хотите избежать получения значения true, если значением является любое из следующего, согласно ответу jAndy :

  • значение NULL
  • не определено
  • NaN
  • пустой строкой ("")
  • 0
  • ложный

Одним из возможных решений, которое могло бы избежать получения истинных значений, является следующее:

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;
    }
}

Это будет использоваться следующим образом:

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!
}

В дополнение к этим сценариям вы можете вернуть false, если объект или массив пуст:

  • Объект: {} (с использованием ECMA 7+ )
  • Массив: [] (с использованием ECMA 5+ )

Вы бы поступили так:

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;
    }
}

Если вы хотите проверить все строки пробелов (""), вы можете сделать следующее:

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

Примечание: hasOwnPropertyвозвращает true для пустых строк, 0, false, NaN, null и undefined, если переменная была объявлена ​​как любая из них, поэтому ее использование может быть не лучшим. Функция может быть изменена, чтобы использовать ее, чтобы показать, что она была объявлена, но ее нельзя использовать.

yaharga
источник
2

Код на 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]';

Бедный мужской тест 😁

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);
};

Результаты теста:

EMPTY (10 tests)
NOT EMPTY (16 tests)
SHOULD BE EMPTY (2 tests)
  Assertion failed: 0: [object Object]
  Assertion failed: 1: [object Map]
Паскаль Поллеунус
источник
отличная функция, у всех других ответов здесь было несколько проблем, которые, по-видимому, решаются вашей, я просто хотел бы найти ее до того, как напишу свою собственную: p Я подумал, что вы могли бы взглянуть на мою работу stackoverflow.com/ questions / 5515310 /… обе наши функции выглядят одинаково, но я немного сократил код. Пожалуйста, дайте мне знать, если я что-то пропустил.
Шон Баннистер
Try Ты пробовал мои "тесты для бедняков"? Я думаю, что я добавил больше тестов в функцию для особых случаев, таких как Map, WeakMap, и, возможно, также Date, RegExp. Вы уверены в своем value.constructor === Object? Проверьте это .
Паскаль Поллеунус
Да, я выполнил ваши тесты, спасибо за то, что обе наши функции возвращают одинаковые результаты с обоими нашими тестами. Я продолжаю задаваться вопросом, пропускаю ли я что-то вне этих тестовых случаев. Я считаю, value.constructor === Objectчто все в порядке, в javascript IF операторы OR имеют порядок выполнения, поэтому оператор OR будет выполняться только в том случае, если предыдущий не вернул TRUE и мы уже проверили Null. Фактически единственная цель этого последнего оператора OR - обнаружить {}и убедиться, что он не возвращает TRUE для вещей, которые он не должен.
Шон Баннистер
1

Это проверит, является ли переменная неопределенного вложения неопределенной

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")) {

Выше проверяет, существует ли функция Google Translate для TranslateElement. Это эквивалентно:

if (!(typeof google === "undefined" 
 || typeof google.translate === "undefined" 
 || typeof google.translate.TranslateElement === "undefined")) {
rickdog
источник
1

Необязательный оператор связывания обеспечивает способ упрощения доступа к значениям через связанные объекты, когда возможно, что ссылка или функция может быть неопределенной или иметь значение null.

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

Нулевой оператор объединения может использоваться после необязательной цепочки для создания значения по умолчанию, когда ничего не найдено:

let customer = {
  name: "Carl",
  details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city
Солнечный султан
источник
1
function notEmpty(value){
  return (typeof value !== 'undefined' && value.trim().length);
}

он также проверит пробелы ('') вместе со следующим:

  • null, undefined, NaN, пусто, строка (""), 0, false
Хасан Али Шахзад
источник
0

Я думаю, используя? Оператор немного чище.

var ? function_if_exists() : function_if_doesnt_exist();
Педро Перейра
источник