Чи є стандартна функція перевірки нульових, невизначених чи порожніх змінних в JavaScript?


2258

Чи існує універсальна функція JavaScript, яка перевіряє, чи має змінна значення і гарантує, що це не так undefinedчи null? У мене цей код, але я не впевнений, чи охоплює він всі випадки:

function isEmpty(val){
    return (val === undefined || val == null || val.length <= 0) ? true : false;
}


78
Протіп, ніколи не роби (truthy statement) ? true : false;. Просто роби (truthy statement);.
Девід Баукум

5
@GeorgeJempty не копій, оскільки інша відповідь запитує зокрема про рядки , тоді як ця запитує про змінні .
Madbreaks

2
Будь-яка правильна відповідь на це запитання повністю залежить від того, як ви визначаєте "порожнє".
Madbreaks

3
@Jay Це нічого не зашкодить, що стосується виконання вашого коду. Це просто надмірно багатослівний. Ви б не сказали: "Ви голодні, це правда?" Ви просто "Ви голодні" Так що в коді просто скажіть if (hungry) …замість if (hungry === true) …. Як і всі кодування речей таким чином, це лише питання смаку. Більш конкретний приклад, наданий ОП, він говорить ще більш докладно: "Якщо це правда, то правда, якщо не то неправда" Але якщо це правда, то це вже правда. І, якщо це неправда, це вже неправда. Це схоже на те, що "Якщо ти голодний, то ти є, а якщо ні, то ні."
Девід Баукум

Відповіді:


4376

Ви можете просто перевірити, чи має зміннаtruthy значення чи ні. Це означає

if( value ) {
}

буде обчислюватися , trueякщо valueце НЕ :

  • нуль
  • невизначений
  • 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


110
Що робити, якщо значення - помилкове булеве значення, яке було призначене. Іноді ви хочете надати значення за замовчуванням, якщо немає значення, яке не спрацює, якщо було передано помилкове булеве значення.
TruMan1

100
@ TruMan1: у такому випадку (коли ваша логіка диктує валідацію), ви повинні ходити if( value || value === false ). Те саме стосується всіх помилкових значень , нам потрібно їх чітко підтвердити.
jAndy

28
За винятком випадків, якщо значення - це масив. Інтерпретація truthyможе бути оманливою. У такому випадку нам слід перевірити value.length != 0наявність порожнього масиву.
користувач

12
Просто хочу додати , що якщо ви відчуваєте , що ifконструкція є синтаксичний занадто важкою, ви можете використовувати потрійний оператор, наприклад , так: var result = undefined ? "truthy" : "falsy". Або якщо ви просто хочете , щоб примушувати до логічного значення, використовуйте !!оператор, наприклад !!1 // true, !!null // false.
KFL

7
Також зауважте, що це не перевірятиметься на рядки, які містять лише символи пробілу.
Крістоф Руссі

220

Дослідний спосіб перевірити, чи значення не визначене чи недійсне:

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

79
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) було б краще дати трохи більше інформації, щоб бути корисним і підштовхнути людей у правильному напрямку. moz doc на різницю developer.mozilla.org/en-US/docs/Web/JavaScript/…
Corey Young

43

Це найбезпечніша перевірка, і я не бачив її тут опублікованою саме так:

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

Він охоплюватиме випадки, коли значення ніколи не визначалося, а також будь-який із них:

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

Відредаговано: Змінено на сувору рівність (! ==), оскільки це норма на даний момент;)


10
Я не спровокував, але що стосується суворого порівняння рівності, загальне правило полягає в тому, що, якщо вам не потрібна неявна конверсія типу, слід застосовувати суворе порівняння.
J.Steve

2
Дякую за ваш коментар Стів. Це загальне правило просто чудово. Я просто розраховую, що для ppl зрозуміють, для чого вони використовують те чи інше. Кожен спосіб, коли ви дивитесь на ppl, буде радий вам проповідувати про те, що "завжди завжди будьте суворі" - як це найважливіше в JavaScript. Я бачив занадто багато випадків, таких як if (val! == null), які, очевидно, призводять до небажаного результату. Чудово сказати, що при сумнівах - використовуйте суворі, але краще не сумніватися.
guya

6
Я думаю, що справа тут у тому, що ми очікуємо, що typeofоператор поверне рядок, тому використання суворої перевірки рівності технічно точніше, конкретніше та швидше. Так що насправді, немає ніяких причин використовувати слабке порівняння, не навпаки. Також val !== nullцілком діє у багатьох випадках - я роблю це постійно. Я погоджуюся з вашим аргументом щодо невідповідності, але я думаю, що це поганий приклад. Не намагаюся вас тролити.
Брайан Даунінг

Спасибі за ваш коментар Брайан, ви використовуєте val! == null, тому що знаєте, що робите. Початківець захоче відмовитись, коли вал фальшивий. Але, val ніколи не буде нульовим, він не буде визначений. Якщо тільки він не прислухався до цієї поради, "щоб завжди завжди використовувати строго", у нього буде менше помилок. Я бачив, як це відбувається у виробничому коді. typeof завжди повертає рядок, і різниця швидкостей буде зайвою. Отже, єдиним аргументом для використання суворого у вищенаведеному випадку є послідовність. Я сказав: "Не потрібно суворої рівності". Це не означає, що ви не можете, якщо хочете, або якщо він робить ваш код більш послідовним.
гайя

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 (солом'яний)." - Саймон Келлберг. автор хоче додати свою підтримку цій прекрасній пропозиції отримати царське сходження.


+1 корисно дізнатись об’єкти типу 'regexp' , 'масив' та 'function'
Yash

@Vix, чому версія ES7 краща?
GollyJer

Це не так, експериментували з більш читабельними способами вираження однієї і тієї ж функціональності, використовуючи: руйнування призначення, оператор зв’язування.
Vix

2
Зауважте, що оператор зв'язування ( ::) взагалі не є частиною ES2016 (ES7), а також будь-яким пізнішим виданням стандарту ECMAScript. Наразі це пропозиція щодо впровадження цієї мови на етапі 0 (солом'яний).
Simon Kjellberg

25

Перша відповідь з найкращим рейтингом - неправильна. Якщо значення не визначене, воно викине виняток у сучасних браузерах. Ви повинні використовувати:

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

або

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

3
eee ... Я думаю, що це неправильно, як якщо б (значення) було достатньо (крім порожніх об'єктів / масивів). якщо значення "невизначене", конфігурація "якщо" не пройде.
Оскар Сзура

3
Це поєднує змінні, які не визначені (які кидають ReferenceError при оцінці), які відрізняються від змінних зі undefinedзначенням.
Qantas 94 Важкий

2
У мене тут така ж помилка. if (x), if (! x), if (!! x) всі помилки будуть кидати, якщо x не визначено.
шаош

if(value === 0) gameOver(); ;)
Madbreaks

Ця відповідь є також помилковою, оскільки вона повертає помилкову, коли valueдорівнює нулю, а це не те, що оп шукає.
Madbreaks

17

Ця перевірка стану

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

це все, що вам потрібно.


Я припускаю, що це просто фрагмент. Але ifвже робиться хибна перевірка, яку це просто перетворює на булеву. Чи вловлює він випадки, які нормальний if(foo)не вловлює?
Даан ван Хулст

1
Це ідеально підходить, коли вам потрібно щось вбудоване, наприклад, мені потрібен атрибут react (званий активним), це правда, коли рядок не порожній - якщо оператор буде надмірним, тому я можу просто використовуватиactive={!!foo}
Бен Коля Менслі,

16

! перевірити порожні рядки (""), null, undefined, false та число 0 та NaN. Скажіть, якщо рядок порожній, var name = ""то console.log(!name)повертається true.

function isEmpty(val){
  return !val;
}

ця функція повертає істину , якщо вал є порожнім, порожнім, не визначене, брехня, число 0 або NaN .

АБО

Відповідно до проблемного домену, ви можете просто використовувати, як !valабо !!val.


Це насправді не говорить про те, якщо змінна порожня, оскільки false та 0 можуть бути дійсними значеннями, а не представляти собою порожнє значення. Значенням функції isEmpty було б переконатися, що очікувані значення є порожніми поверненнями. на мою думку null, undefined, NaN та порожня рядок - це значення, які мають сенс як порожні.
Corey Young

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

Ви трохи перестараєтесь. Щоб перевірити, чи змінній не присвоєно значення, потрібно було б лише перевірити, чи не визначено та null.

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

Це припущення 0, ""і об'єкти (навіть порожній об'єкт та масив) є дійсними "значеннями".


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

В іншому випадку, якщо ви вже використовуєте підкреслення або позначення, спробуйте:

_.isEmpty(value)

3
Спробували ваш код. Я отримую повідомлення про помилку в консолі, яке говорить: "Невизначена помилка посилання: isArray () не визначено". Інакше було б чудово, якби це спрацювало.
crmprogdev

11
Щонайменше у випадку лодашу _.isNil- це та функція, яку ви шукаєте, ні _.isEmpty. isNil документація , isEmpty документація
Snixtor

Це не вдасться, якщо значення булеве і має значення true.
kalyanbk

3
Простий javascript не має isArrayабо isStringфункціонує на window.
GFoley83

@ GFoley83 - Ти мене зловив! У мене є свої причини не використовувати Windows. Я фактично висвітлюю цю тему в розділі, який розповідає про історію та розвиток програмних мов. Більш релевантною інформацією, швидше за все, стане дискусія / код, що демонструє монадичне поводження з помилками в моїй книзі, Дізнайтеся про функціональне програмування в роботі. Ура!
l3x

9

Ось моя - повертає істину, якщо значення є нульовим, невизначеним тощо або порожнім (тобто містить лише порожні пробіли):

function stringIsEmpty(value) {

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

}

1
Я зробив тест на кілька методів тут. З чеком на невизначеність, ваша функція чудово працює. Тому я використовую if (typeof value! == 'undefined' &&! IsEmpty (value)) АБО, якщо ви насправді хочете перевірити порожній, ви можете використовувати if (typeof value === 'undefined' || IsEmpty2 (value) ). Це буде працювати для нуля; Невизначений; 0; ""; ""; false
RationalRabbit

6
return val || 'Handle empty variable'

це дійсно приємний і чистий спосіб впоратися з ним у багатьох місцях, його також можна використовувати для призначення змінних

const res = val || 'default value'

Багато місць , але не тоді , коли за замовчуванням , 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
}

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

2
Ви можете пояснити, будь ласка. що там відбувається
JoshKisb

Масив містить деяку змінну, яку ви вважали порожньою.
ddagsan

@JoshKisb усі значення масиву представляють те, що ви хочете бути (нульові, невизначені чи інші речі), і ви шукаєте в ньому те, що ви хочете.
ddagsan

1
@ddagsan Хоча JoshKisb може оцінити вашу відповідь, ви повинні розмістити свої пояснення у відповіді, а не в коментарях
Nick

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 ніколи не повинна стосуватися загально.


Правдивість / хитрість

Щоб вирішити, як визначити "вакуумність" значень, нам потрібно врахувати вбудований javascript, властивий йому сенс того, чи є значення "truthy" чи "false". Природно, nullі undefinedвони обидва "хибні". Менш природно, число 0(і жодне інше число, крім NaN) теж "хибне". Найменше, природно: ''хибний, але []і {}new Set(), і new Map()) є неправдивими, хоча всі вони здаються однаково вакуумними!


Нуль проти невизначеного

Існує також деяка дискусія щодо nullvs undefined- чи нам справді потрібні обидва, щоб виразити нерішучість в наших програмах? Я особисто уникаю того, щоб літери u, n, d, e, f, i, n, e, d відображалися в моєму коді в такому порядку. Я завжди використовую nullдля позначення "вакуумності". Знову ж таки, нам потрібно відповідати властивому JavaSkript почуттю того, як 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');
}

  • Завжди використовуйте "білі списки" для перевірки. Якщо вам потрібне значення, наприклад, рядок, номер або масив, перевірте ці 3 "білі" можливості і введіть помилку, якщо жоден з 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) умов на перевірку, як не null, not blank, not undefined and not zero, використовуйте лише цей код (! (! (Змінна))) у 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);
    }
}

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

2

Якщо ви хочете уникнути отримання істини, якщо значення має якесь із наведених нижче, відповідно до відповіді jAndy :

  • нуль
  • невизначений
  • 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!
}

Крім цих сценаріїв, ви можете повернути помилкове значення, якщо об’єкт або масив порожні:

  • Об'єкт: {} (Використання 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, якщо змінна була оголошена як будь-яка з них, тому вона може бути не найкращою для використання. Функція може бути змінена, щоб використовувати її, щоб показати, що вона була оголошена, але вона не є корисною.


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/ питання / 5515310 /…, як видається, обидві наші функції мають однаковий вихід, але я трохи скоротив код. Будь ласка, дайте мені знати, якщо я щось пропустив.
Шон Банністер

👍 Ви пробували мої "Випробування бідної людини"? Думаю, що я додав ще тестів у функції для особливих випадків, таких як Map, WeakMap, а може бути, і Date, RegExp. Ви впевнені у своєму value.constructor === Object? Перевірте це .
Паскаль Поллеун

Так, я виконував ваші тести, дякую за те, обидві наші функції повертають однакові результати з обома нашими тестами. Мені постійно цікаво, чи пропускаю я щось поза межами цих тестових випадків. Я вважаю, що value.constructor === Objectце нормально, у javascript АБО АБО оператори мають порядок виконання, так що оператор АБО виконуватиметься лише в тому випадку, якщо попередній не повернув TRUE і ми вже перевірили Null. Насправді єдина мета цього останнього оператора АБО - виявити {}та переконатися, що він не повертає ІСТИНУ для речей, які він не повинен.
Шон Банністер

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 TranslateElement. Це еквівалентно:

if (!(typeof google === "undefined" 
 || typeof google.translate === "undefined" 
 || typeof google.translate.TranslateElement === "undefined")) {

1

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

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, empty, string (""), 0, false

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.