Як я можу визначити, чи є змінна "undefined" або "null"?


2126

Як визначити, чи є змінною undefinedабо null?

Мій код такий:

var EmpName = $("div#esd-names div#name").attr('class');
if(EmpName == 'undefined'){
  // DO SOMETHING
};
<div id="esd-names">
  <div id="name"></div>
</div>

Але якщо я це зробити, інтерпретатор JavaScript зупиняє виконання.


Відповіді:


2847

Ви можете використовувати якості оператора абстрактної рівності для цього:

if (variable == null){
    // your code here.
}

Оскільки null == undefinedце правда, наведений вище код буде ловити і те, nullі undefined.


5
Я намагаюся перевірити, чи подія є недійсною у firefox і помилка блокує виконання: "подія не визначена"
Entretoize

3
@MichaelFever Як це не працює? Скопіюйте це в консоль: const y = undefined; y == null;Це має повернутисяtrue
Сераф

2
@ChrisStryczynski У прикладі свого коментаря ви оголосили yпостійним, але ви порівнюєте посуд abc(не y). Коли я тестував yчерез console.log(y == null);на Chrome і Firefox я отримав trueв результаті. Якщо у вас виникла помилка, можливо, ви спробували використати оператор присвоєння =замість порівняння, ==який має сенс повернути помилку, оскільки constне може бути перепризначений.
Пшемо

2
живий приклад відповідних порівнянь. lgtm.
Ryan Haining

2
@ZaytsevDmitry, чому б ви очікували тесту, якщо змінна є nullабо undefinedпройде, якщо змінна дорівнює 0? Питання полягає не в тестуванні на надійне значення, а в скорішому тестуванні на nullабо undefined.
rodrigo-silveira

1106

Стандартний спосіб лову nullі undefinedодночасно такий:

if (variable == null) {
     // do something 
}

- що на 100% еквівалентно більш явним, але менш стислим:

if (variable === undefined || variable === null) {
     // do something 
}

Коли пишуть професійні JS, це зрозуміло, що рівність типу і поведінка ==vs=== розуміється. Тому ми використовуємо ==і лише порівнюємо їх null.


Відредагуйте ще раз

Зауваження, що пропонують використання typeof, просто неправильні. Так, моє рішення вище спричинить ReferenceError, якщо змінної не існує. Це гарна річ. Цей ReferenceError бажаний: він допоможе вам знайти свої помилки та виправити їх перед тим, як надсилати код, як і помилки компілятора в інших мовах. Використовуйте try/ catchякщо ви працюєте з введенням, ви не маєте контролю над.

У вашому коді не повинно бути посилань на незадекларовані змінні.


47
Це спричинить виконання ReferenceError та розрив, якщо змінна не визначена або згадується взагалі в коді, використання typeof безпечніше.
Мані Гандхем

56
Це більше стилістичний момент. Якщо змінна не була оголошена на все , що насправді просто погано письмовій формі з боку автора. Ви повинні знати, була задекларована ваша змінна чи ні, це не повинно бути питанням. Але так , якщо з якихось причин це так, це слід змінити на window.variable замість просто змінної , що не спричинить помилку посилання. Слід уникати типу.
тимчасовий_користувач

6
Так, тому що ви писали !==замість !=.
тимчасове_користувач_12

9
-OP: Заява про те, що ці порівняння є "100% еквівалентом" є ПРОСТО НЕВЕРШЕНО, як ви зазначали у вашій власній EDIT, друге викликає ReferenceError. Щодо твердження: "У вас не повинно бути посилань на незадекларовані змінні у вашому коді." Справді? Коли-небудь чули про необов’язкові параметри? jsfiddle.net/3xnbxfsu
Тимофій Канський

16
Факультативні параметри @TimothyKanski можуть бути невизначені, якщо вони необов'язково не надаються, але вони є найбільш визначеними змінними. Вони оголошені і мають значення undefined, як і будь-яка заявлена, але неініціалізована змінна, тобто var someVar;ваш аргумент насправді не витримує
chiliNUT

227

Поєднуючи вищезазначені відповіді, видається, що найповнішою відповіддю буде:

if( typeof variable === 'undefined' || variable === null ){
    // Do stuff
}

Це має працювати для будь-якої змінної, яка або незадекларована, або оголошена, і явно встановлена ​​на нуль або невизначена. Булевий вираз має оцінюватися як хибний для будь-якої оголошеної змінної, яка має фактичне ненульове значення.


2
@Aerovistae Я визнаю, що typeofце оператор, а не функція, тому він не потребує круглих дужок, але я оцінюю круглі дужки - просто для чіткості читання.
user664833

1
а як безпосередньо перевірити, якщо (змінний === невизначений), а не використовувати typeof?
Заморожений олівець

2
@ArjunU, що спричинить ReferenceError, якщо змінна не буде оголошена. Якщо ви не знаєте, чи оголошена змінна чи ні, використовуйте наведене вище рішення. Якщо ви можете гарантувати, що змінна хоча б оголошена, можете скористатисяvariable == null
Rogue

3
Це краще рішення, оскільки, як зазначав @Rogue, змінна може не бути оголошена.
Абдул Садік Ялцін

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

186
if (variable == null) {
    // Do stuff, will only match null or undefined, this won't match false
}

14
На всякий випадок, коли хтось вважає, що це ще одна напіввідповідь, це насправді працює. undefinedоцінює рівний null.
Чак

3
Не вдалося мені в хромованій консолі ... ReferenceError: змінна не визначена, тому вона може працювати, але не для мене ...
Eran Medan

48
Він працює лише для оголошених змінних, а не змінних, які можуть бути або не можуть бути оголошені, що рідко буває. (Для цього потрібно використовувати typeof + нульовий чек)

11
Щойно зрозумів, що ви можете додати цей коментар: /*jshint eqnull:true */у верхній частині документа або функції JS, і JSHint перестане попереджати вас про ваше використання == null.
Web_Designer

3
@Aerovistae Ви можете вказати мені на посилання, в якому прямо вказано, що ==це порушено. Примус if(variable == null)у цій відповіді має повний сенс для мене ...
Бен Астон,

93
if (typeof EmpName != 'undefined' && EmpName) {

оцінюється як вірно, якщо значення не:

  • нуль

  • невизначений

  • NaN

  • порожній рядок ("")

  • 0

  • помилковий


13
Я думаю, що це небезпечна техніка, яка поширилася, як дикий вогонь. Тому що багато перевірених змінних можуть бути булевими чи числами. Тож якщо користувач не повністю розуміє наслідки, це не добре.
корисноБез

Будь ласка, надайте посилання на цю специфікацію javascript
villamejia

1
Це те саме, що if (EmpName). Якщо вже undefinedбуде фальшиво.
Руді

Якщо змінна не визначена. тоді, якщо (EmpName) приведе помилку
Thamaraiselvam

1
@Thamaraiselvam Я думаю, що Руді міг це означати var EmpName; if (EmpName). Де змінна визначена, але не присвоєне значення.
голод

27

attr()Функція jQuery повертає або порожній рядок, або фактичне значення (і ніколи nullабо undefined). Єдиний раз, коли він повертаєтьсяundefined це коли ваш селектор не повернув жодного елемента.

Тому ви можете перевірити чистий рядок. Крім того, оскільки порожні рядки, null та undefined є false-y, ви можете просто зробити це:

if (!EmpName) { //do something }

1
Chrome 17.0.963.78 м дає цю помилку:ReferenceError: EmpName is not defined
Еран Медан

6
@EranMedan Я знаю, що це пізно, але, сподіваюся, допоможе людям, які приїдуть сюди пізніше. Причина, за якою ви отримуєте помилку, полягає в тому, що вона взагалі не була оголошена. Зазвичай ви мали б передати EmpName (або якусь іншу змінну) у функцію або повернути значення іншої функції і тому оголосити (Приклад: "var x;"). Щоб перевірити, чи він повернув невизначений, нульовий чи порожній рядок, ви можете скористатися вищевказаним рішенням.
Дейв

Я усвідомлюю, що це холодне питання, але jQuery повернеться, undefinedякщо атрибут не існує в елементі (не тільки в тому випадку, якщо в селекторі немає відповідних елементів, відповідно до відповіді). Наприклад, an imgwith no srcне повернеться undefinedза$('img').attr('src');
кодування

19

Я прийшов написати свою функцію для цього. JavaScript дивний.

Він використовується практично на будь-якому місці. (Зверніть увагу, що це також перевіряє, чи змінна містить якісь корисні значення . Але оскільки ця інформація зазвичай також потрібна, я думаю, що її варто опублікувати). Просимо залишити записку.

function empty(v) {
    let type = typeof v;
    if (type === 'undefined') {
        return true;
    }
    if (type === 'boolean') {
        return !v;
    }
    if (v === null) {
        return true;
    }
    if (v === undefined) {
        return true;
    }
    if (v instanceof Array) {
        if (v.length < 1) {
            return true;
        }
    } else if (type === 'string') {
        if (v.length < 1) {
            return true;
        }
        if (v === '0') {
            return true;
        }
    } else if (type === 'object') {
        if (Object.keys(v).length < 1) {
            return true;
        }
    } else if (type === 'number') {
        if (v === 0) {
            return true;
        }
    }
    return false;
}

Сумісний з TypeScript


Ця функція повинна виконувати точно так само, як і empty()функцію PHP (дивRETURN VALUES )

Вважає undefined, null, false, 0, 0.0, "0" {}, []як порожні.

"0.0", NaN, " ", trueВважаються не порожньо.


2
Я зіткнувся з невеликою проблемою перевірки нуля. Я хочу перевірити, чи не переданий параметр є нульовим, чи порожнім об'єктом { }. Це поширена і дурна мовна проблема, але я про неї забув. Усі мої пошукові запити показують відповіді на невизначене нульове значення або порівняння вільної рівності (==), але не сувору рівність (===) або еквівалент. І тоді, у вашій 1-ми ранжированій відповіді в самому нижній частині сторінки (до того, як я прийняв заяву), є відповідь, яка мені ухилилася. Object.keys( obj ).length < 1а може бути === 0, якщо припустити, що це ніколи не буде -1. У будь-якому разі, дозволено до 0, ву. : p

Дякую, мені вдалося скинути цю функцію та очистити багато коду. Чому це не стандартна функція JS - це поза мною.
Енді

3
Ви повинні змінити все своє ==на ===тут, тоді це було б розумною функцією.
Бен Макінтайр

12

Якщо змінна, яку ви хочете перевірити, є глобальною, зробіть це

if (window.yourVarName) {
    // Your code here
}

Цей спосіб перевірки не призведе до помилки, навіть якщо yourVarNameзмінна не існує.

Приклад: я хочу знати, чи підтримує мій браузер API History

if (window.history) {
    history.back();
}

Як це працює:

windowце об'єкт, який містить усі властивості глобальних змінних як свої властивості, а в JavaScript законно намагатися отримати доступ до неіснуючої властивості об'єкта. Якщо historyйого немає, то window.historyповертається undefined. undefinedє фальсі, тому код у if(undefined){}блоці не запускається.


2
Читачі мають зауважити, що такий підхід є ідіоматичним для перевірки - від JavaScript, що працює в браузері - чи оголошена глобальна змінна, і особливо, чи доступний глобальний браузер (як API історії). Він не працюватиме для перевірки того, чи є неглобальна змінна nullчи undefinedне буде працювати, якщо ваш JavaScript працює поза браузером (тобто в Node.js). Він також стосуватиметься глобальних установок, встановлених 0, falseабо ''таких самих, як ті, які не є оголошеними або, undefinedабо null, як правило, добре.
Марк Амері

Це передбачає, що сценарій працює в браузері. Це не дано.
GreenAsJade

12

Найкоротший і найпростіший:

if(!EmpName ){
 // DO SOMETHING
}

це оцінить істину, якщо EmpName:

  • нуль
  • невизначений
  • NaN
  • порожній
  • string ("")
  • 0
  • помилковий

3
Приклад використання полягає в тому, що я хочу знати різницю між невизначеним і хибним. Тоді я використаю чек на null.
gast128

11

Напевно, найкоротший спосіб це зробити:

if(EmpName == null) { /* DO SOMETHING */ };

Ось доказ:

А тут докладніше про ==(джерело тут )

Введіть тут опис зображення

БОНУС : причина, чому ===більш зрозуміла, ніж ==(дивіться на відповідь agc )

Введіть тут опис зображення


8

У мене щойно була ця проблема, тобто перевірка, чи об’єкт недійсний.
Я просто використовую це:

if (object) {
    // Your code
}

Наприклад:

if (document.getElementById("enterJob")) {
    document.getElementById("enterJob").className += ' current';
}

3
було б краще встановити var A = document.getElementById ("enterJob"), якщо (A) A.className + = 'current'; таким чином ви робите 50% роботи для того ж результату ... Але, можливо, ви просто зробили це для шоу, і тоді я вітаю.
Гаррі Свенссон

7

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

var s; // undefined
jQuery.isEmptyObject(s); // will return true;

s = null; // defined as null
jQuery.isEmptyObject(s); // will return true;

// usage
if(jQuery.isEmptyObject(s)){
    alert('Either variable: s is undefined or its value is null');
}else{
     alert('variable: s has value ' + s);
}

s = 'something'; // defined with some value
jQuery.isEmptyObject(s); // will return false;

Це для мене не вийшло. Я все-таки отримав помилку: ReferenceError: s is not definedдля першого прикладу.
Марк

5

Елемент перевірки jQuery не має нуля:

var dvElement = $('#dvElement');

if (dvElement.length  > 0) {
    // Do something
}
else{
    // Else do something else
}

4

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

if (variable === undefined){
}

if (variable === null){
}

if (variable === ''){
}

Перевірте всі умови:

if(variable === undefined || variable === null || variable === ''){
}

varце зарезервоване слово, це кинеSyntaxError
dhilt

4

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

if (x === null || x === undefined) {
 // Add your response code here, etc.
}

3

Найпростіший спосіб перевірити:

if(!variable) {
  // If the variable is null or undefined then execution of code will enter here.
}

1
Це виконає код, якщо змінна має значення false, яке потенційно є небажаним.
byxor

Питання зрозуміло: "Як визначити, чи змінна" невизначена "чи" нульова "?" а в JavaScript, якщо змінна має значення null або undefined, її значення false.
М. Арнольд

1
Вибачте, але це неправильно. Ось JSfiddle, щоб довести це.
byxor

Судячи з вашої відповіді, undefined, null і кілька інших речей , як порожній рядок, +0, -0 NaNі falseотримати. !оператор примушує операнда variable- тут - Булеву
Аліреза

Але перевірте питання: "Як визначити, чи змінна не визначена чи нульова", the! операнд, який використовується з if, завжди повернеться до істинного, якщо змінна є нульовою чи невизначеною.
М. Арнольд

2

З рішенням нижче:

const getType = (val) => typeof val === 'undefined' || !val ? null : typeof val;
const isDeepEqual = (a, b) => getType(a) === getType(b);

console.log(isDeepEqual(1, 1)); // true
console.log(isDeepEqual(null, null)); // true
console.log(isDeepEqual([], [])); // true
console.log(isDeepEqual(1, "1")); // false
etc...

Я можу перевірити наступне:

  • нуль
  • невизначений
  • NaN
  • порожній
  • string ("")
  • 0
  • помилковий

Це не дає відповіді на запитання, яке є "як я вловлю нульові та невизначені?" не "як я вловлюю кожне значення фальси в JavaScript?"
тимчасове_користувач_ім'я

@Aerovistae, я думав, що я зробив з console.log (isDeepEqual (null, null)); і console.log (isDeepEqual (undefined, undefined)); ?
Тоні Тай Нгуен

1

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

    if(typeof sVal === 'undefined' || sVal === null || sVal === ''){
      console.log('variable is undefined or null');
    }

Близько, але ні. Втратити typeofі порівняти undefinedпрямо, а не як струну. Це працює, але додатковий оператор не має ніякого ефекту, крім того, щоб зробити його більш здоровим.
тимчасовий_користувач

У цьому випадку так, ви праві, нам не потрібно використовувати typeof. Але корисно використовувати typeof, коли ви маєте справу з невизначеними змінними. Однією з причин використання typeof є те, що він не видає помилку, якщо змінна не була оголошена.
DanKodi

Це насправді погано. Ви не хочете, щоб у коді були недекларовані змінні. Ви хочете, щоб кинути ReferenceError, щоб ви могли знайти змінну і оголосити її. Звичайно, ви б не спробували цього на мові, складеній на зразок C ++! Тільки тому, що JS дозволяє це не означає, що це потрібно робити.
тимчасовий_користувач

1
Ваше висловлювання або зворотний зв'язок. Перевірка того, що щось не визначено, буде першим кроком, а не другим.
Ентоні Рутлідж

1

Я запускаю цей тест у консолі Chrome. Використовуючи (void 0), ви можете перевірити невизначений:

var c;
undefined
if (c === void 0) alert();
// output =  undefined
var c = 1;
// output =  undefined
if (c === void 0) alert();
// output =   undefined
// check c value  c
// output =  1
if (c === void 0) alert();
// output =  undefined
c = undefined;
// output =  undefined
if (c === void 0) alert();
// output =   undefined

1

Подивимось на це,

  1.  

    let apple; // Only declare the variable as apple
    alert(apple); // undefined

    У вищесказаному змінна оголошується лише як apple. У цьому випадку, якщо ми викликаємо метод, alertвін відображатиметься невизначеним.

  2.  

       let apple = null; /* Declare the variable as apple and initialized but the value is null */
       alert(apple); // null

У другому він відображає нуль, тому що змінна apple значення є нульовою.

Таким чином, ви можете перевірити, чи значення не визначене чи недійсне.

if(apple !== undefined || apple !== null) {
    // Can use variable without any error
}

0

Кращий спосіб:

if(typeof variable==='undefined' || variable===null) {

/* do your stuff */
}

6
Це точне рішення вже було надано @jkindwall 11 жовтня 2013 року. Stackoverflow.com/a/19323555/2943403 Ця публікація, кодована лише кодом, є абсолютно марною, оскільки не додає нової цінності на сторінку. Насправді це додає роздуття сторінки і витрачає дослідників час на її читання. Видаліть цю відповідь.
mickmackusa

0
(null == undefined)  // true

(null === undefined) // false

Тому що === перевіряє і тип, і значення. Тип обох різний, але значення однакове.


0
var i;

if (i === null || typeof i === 'undefined') {
    console.log(i, 'i is undefined or null')
}
else {
    console.log(i, 'i has some value')
}

3
Що станеться, якщо користувач введе слово "невизначений"?
Чак

Ваше запитання добре, він показує, що умова відповідає дійсності, тому нам потрібно змінити параметр, який не визначається, на умову typeof. @Chuck
KARTHIKEYAN.A

Це неправильно. typeofніколи не поступиться undefined, тільки рядок 'undefined'. Більше того, i == nullце вже правда, якщо iє undefined, тож другий булевий сигнал буде зайвим, навіть якби він працював.
тимчасове_користувач_ім'я

1
Це рішення (із зміненими умовами) вже було надано @jkindwall 11 жовтня 2013 року. Stackoverflow.com/a/19323555/2943403 Ця публікація, кодована лише для коду, є абсолютно марною, оскільки не додає нової цінності на сторінку. Насправді це додає роздуття сторінки і витрачає дослідників час на її читання. Видаліть цю відповідь.
mickmackusa

0

foo == nullЧек повинен зробити трюк і вирішити «невизначений або нульовий» випадок в найкоротшому. (Не враховуючи випадку "foo не оголошено".) Але люди, які звикли мати 3 рівні (як найкраща практика), можуть не прийняти це. Просто подивіться на eqeqeq або потрійні рівні правила в eslint та tslint ...

У цьому випадку слід застосовувати явний підхід, коли ми перевіряємо, чи є змінна undefinedчи nullокремо, і мій внесок у тему (27 негативних відповідей на даний момент!) Полягає у використанні void 0як короткого, так і безпечного способу перевірки. для undefined.

Використання foo === undefinedне є безпечним, оскільки невизначене не є зарезервованим словом і може бути затіненим ( MDN ). Використання typeof === 'undefined'перевірки є безпечним, але якщо ми не будемо піклуватися про нерозголошений варіант foo-is-notcreen, можна використовувати наступний підхід:

if (foo === void 0 || foo === null) { ... }

0

якщо ви створили функцію для перевірки:

export function isEmpty (v) {
 if (typeof v === "undefined") {
   return true;
 }
 if (v === null) {
   return true;
 }
 if (typeof v === "object" && Object.keys(v).length === 0) {
   return true;
 }

 if (Array.isArray(v) && v.length === 0) {
   return true;
 }

 if (typeof v === "string" && v.trim().length === 0) {
   return true;
 }

return false;
}

-1

Виклик typeof null повертає значення "object", оскільки спеціальне значення null вважається порожнім посиланням на об'єкт. У Safari через версію 5 та Chrome на версію 7 є примірник, коли виклик typeof у регулярному виразі повертає "функцію", а всі інші браузери повертають "об'єкт".


-1
var x;
if (x === undefined) {
    alert ("only declared, but not defined.")
};
if (typeof y === "undefined") {
    alert ("not even declared.")
};

Ви можете використовувати лише друге: як це перевірятиметься як на визначення, так і на оголошення


-1

Я все ще думаю, що найкращий / безпечний спосіб перевірити ці дві умови - це передати значення рядку:

var EmpName = $("div#esd-names div#name").attr('class');

// Undefined check
if (Object.prototype.toString.call(EmpName) === '[object Undefined]'){
    // Do something with your code
}

// Nullcheck
if (Object.prototype.toString.call(EmpName) === '[object Null]'){
    // Do something with your code
}

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

Оскільки перетворення завжди повертає "стандартизовану" рядок (тобто [object Undefined]), тому ви не потрапите в проблеми, перевіряючи помилкові значення. Ось тільки моя думка, заснована на досвіді, який я мав з цінностями "фальшиві / хибні".
n1kkou

Дякую за пояснення. Я не критикую її цікаву відповідь, я просто хотів, щоб ви дали пояснення для інших, чому це потенційно перевершує інші методи.
sadmicrowave

Не хвилюйтесь! У мене було багато проблем із цим типом порівнянь, і до цих пір я вважаю це найбільш корисним підходом до цього питання.
n1kkou

-2

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

if(typeof value == 'undefined'){

Дивіться коментарі в попередній відповіді ( stackoverflow.com/a/21273362/6305294 ) стосовно typeof.
Алекс

4
Це неправильно. Не ловить null. Я не розумію, чому надаються нові, невірні відповіді на питання, на яке було дано правильну і повну відповідь багато років тому. Чи вважаєте ви, що нинішні відповіді якимось чином недостатні?
тимчасове_користувач

-4

if(x==null)погана ідея в JavaScript. Судіть із "=="- це може спричинити несподіваний примус типу, і він не може читати CoffeeScript, ніколи не використовуйте "==" або "! =" За умови судження!

if(x)буде краще, але будьте обережні з 0 і "" . Це буде розглядатися як помилковий , а не рівні метод з "!= null"це вірно .

Введіть тут опис зображення

Див. Найкращі практики JavaScript .


3
Це абсолютно невірно, і помірне вивчення будь-якої програми чи програмного забезпечення професійного рівня підтвердить це протягом декількох моментів. Використання ==для порівняння null- це стандартний спосіб лову nullта undefinedв JS. Введіть примус із== не є ризиком у цьому конкретному контексті, і насправді його використовують для досягнення мети спіймання обох nullі undefinedодночасно. Будь ласка, витрачайте більше часу на роботу з мовою, перш ніж обрати, щоб запропонувати невірні та оманливі відповіді на питання, які були задовільно вирішені років тому.
тимчасовий_користувач

уникати "==". Все завжди змінюється, я з вами не погоджуюся @Aerovistae
Albert.Qing

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