Чому null є об’єктом і яка різниця між null та undefined?


866

Чому nullвважається анobject JavaScript?

Перевірка

if ( object == null )
      Do something

такий же як і

if ( !object )
      Do something

?

А також:

У чому різниця між nullі undefined?


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

6
Null не є об’єктом у JavaScript! typeof null === 'object'але це помилка! Ось посилання Переглянути всі відео і насолоджуватися :)
CoR

1
Мені подобається використовувати C / C ++ як аксіоматичну істину для не визначеної та NULL-змінної змінної, оскільки це дуже просто. Потім подивіться, як ці визначення порівнюються зі специфікаціями інших мов.
Саміс

Відповіді:


1488
(name is undefined)

Ви: Що таке name? (*)
JavaScript name :? Що таке name? Я не знаю, про що ти говориш. Ви ніколи раніше ні про кого не згадували name. Чи бачите ви якусь іншу мову сценаріїв на стороні (клієнт)?

name = null;

Ви: Що таке name?
JavaScript: Я не знаю.

Коротко; undefinedде немає поняття про річ; він не має типу, і ніколи раніше в цьому обсязі не посилалися;nullтам, де річ, як відомо, існує, але невідомо, у чому цінність.

Одна річ , щоб пам'ятати, що nullце не так , концептуально, так само , як falseі ""чи такий, навіть якщо вони прирівнюють після типу лиття, тобто

name = false;

Ви: Що таке name?
JavaScript: Булева помилка.

name = '';

Ви: Що таке name?
JavaScript: Порожній рядок


*: nameу цьому контексті мається на увазі як змінна, яка ніколи не була визначена. Це може бути будь-яка невизначена змінна, однак ім'я є властивістю майже будь-якого елемента форми HTML. Він іде шляхом, назад і був заведений задовго до ід. Це корисно, оскільки ідентифікатори повинні бути унікальними, але імена не повинні бути.


14
Але в JavaScript порожній рядок '' все ще булева помилка.
Андреас Греч

117
Порожній рядок не є булевим помилковим, але в контексті умовного він трактується як хибне (у) значення (примус).
Брайан Меттьюз

22
У другому випадку, коли name = null, замість 'I don't know', JavaScript може відповісти: null object. Крім цього мені подобається стиль відповіді.
Жан Вінсент

16
Замість того, щоб "я не знаю", я б сказав, що відповідь null- "нічого". Нуль точно визначається як відсутність значення. Пустота, нуль, нада. Нічого.
mikl

50
Любіть цей стиль відповідей. Загалом, "Ви ніколи раніше ні про кого не згадували name " це правда. Однак оголошення про змінну без присвоєння їй значення ( var somevar;), напрочуд, все одно призведе до undefined.
MC імператор

142

Різницю можна підсумувати в цей фрагмент:

alert(typeof(null));      // object
alert(typeof(undefined)); // undefined

alert(null !== undefined) //true
alert(null == undefined)  //true

Перевірка

object == nullінша перевірка if ( !object ).

Останній дорівнює ! Boolean(object), тому що одинарний! оператор автоматично передає правильний операнд в булевий.

Так як Boolean(null)дорівнює хибність !false === true.

Отже, якщо ваш об’єкт недійсний , але неправдивий або 0 або "" , перевірка пройде, оскільки:

alert(Boolean(null)) //false
alert(Boolean(0))    //false
alert(Boolean(""))   //false

@kentaromiura Для нас Javascript noobs ... можливо, тільки я ... що це булевий (значення) синтаксис? Кастинг до булевого?
xr280xr

@ xr280xr Так, це кастинг. Спробуйте String(null)побачити інший приклад кастингу. Ви навіть можете робити такі дурні речі, як Number(null + 2)... але не варто :-). Відмінна відповідь від кентароміури.
кальмар

Пам'ятайте typeof, це оператор. Ви б не загорнули операнда в дужки з тієї ж причини, яку не написали б var sum = 1 +(1);.
alex

124

nullце не є об'єктом , це елементарне значення . Наприклад, ви не можете додати в нього властивості. Іноді люди неправильно припускають, що це об’єкт, тому що typeof nullповертається "object". Але це насправді помилка (яка може бути навіть виправлена ​​в ECMAScript 6).

Різниця між nullта undefinedполягає в наступному:

  • undefined: використовується JavaScript та означає "немає значення". Неініціалізовані змінні, відсутні параметри та невідомі змінні мають це значення.

    > var noValueYet;
    > console.log(noValueYet);
    undefined
    
    > function foo(x) { console.log(x) }
    > foo()
    undefined
    
    > var obj = {};
    > console.log(obj.unknownProperty)
    undefined

    Однак доступ до невідомих змінних створює виняток:

    > unknownVariable
    ReferenceError: unknownVariable is not defined
  • null: використовується програмістами для позначення "немає значення", наприклад, як параметр функції.

Вивчення змінної:

console.log(typeof unknownVariable === "undefined"); // true

var foo;
console.log(typeof foo === "undefined"); // true
console.log(foo === undefined); // true

var bar = null;
console.log(bar === null); // true

Як правило, у JavaScript завжди слід використовувати === і ніколи == (== виконує всі види перетворень, які можуть призвести до несподіваних результатів). Перевірка x == nullявляє собою крайній випадок, тому що він працює для обох nullі undefined:

> null == null
true
> undefined == null
true

Поширений спосіб перевірити, чи має змінна значення, - це перетворити її на булеву і подивитися, чи є вона true. Це перетворення виконується ifоператором і булевим оператором! ("Ні").

function foo(param) {
    if (param) {
        // ...
    }
}
function foo(param) {
    if (! param) param = "abc";
}
function foo(param) {
    // || returns first operand that can't be converted to false
    param = param || "abc";
}

Недолік такого підходу: усі наведені нижче значення оцінюються false, тому ви повинні бути обережними (наприклад, вищеперелічені перевірки не можуть розрізняти undefinedі 0).

  • undefined, null
  • Булеви: false
  • Числа: +0, -0,NaN
  • Струни: ""

Ви можете перевірити перетворення на булевий, використовуючи Booleanяк функцію (зазвичай це конструктор, який слід використовувати new):

> Boolean(null)
false
> Boolean("")
false
> Boolean(3-3)
false
> Boolean({})
true
> Boolean([])
true

1
Навіщо посилатися +0і -0окремо, якщо +0 === -0?
Райнос

6
Ймовірно тому , що ви до сих пір можна розрізнити +0і -0: 1/+0 !== 1/-0.
нео

1
Ця відповідь посилається на повідомлення, яке посилається на цю відповідь як джерело ... ймовірно, означало посилання на це замість 2ality.com/2013/10/typeof-null.html
Рікардо Томасі

Так, як у C, де неініціалізовані декларації змінної вважаються невизначеними (старі версії фактично можуть містити дані попередніх програм).
Саміс

5
"Але це насправді помилка (яку можна навіть виправити в ECMAScript 6)" - джерело?
Gajus

26

Яка різниця між нульовим та невизначеним ??

Властивість, коли вона не має визначення, не визначена. null - об’єкт. Його тип - об’єкт. null - це особливе значення, що означає "немає значення. undefined не є об'єктом, його тип не визначений.

Ви можете оголосити змінну, встановити її на нуль, а поведінка ідентична, за винятком того, що ви побачите "null", роздруковані проти "undefined". Можна навіть порівняти змінну, яка не визначена з нульовою, або навпаки, і умова буде вірною:

 undefined == null
 null == undefined

Детальнішу інформацію див. У JavaScript Різниця між null та undefined .

і з новою редакцією так

if (object == null)  does mean the same  if(!object)

при тестуванні, якщо об'єкт неправдивий, вони обидва відповідають умові при тестуванні, якщо неправдивим , але не істинним

Перевірте тут: JavaScript gotcha


4
Ви повинні використовувати ===, а потім не
визначити

1
зверніть увагу на останню частину, невірно див. мою відповідь;)
kentaromiura

6
! об'єкт - це не те саме, що "object == null" ... Насправді вони зовсім інші. ! об'єкт поверне вірно, якщо об'єкт дорівнює 0, порожня рядок, булева помилка, невизначена або нульова.
Джеймс

3
Чи дійсно null об’єкт? Перше надане вами посилання перевіряє null за typeof, але typeof (null) оцінює "об’єкт" через помилку дизайну мови.
c4il

2
nullне є об’єктом. Це typeof null == 'object';повертає справжнє через помилку, яку неможливо виправити в JavaScript (зараз, але може змінитися в майбутньому).
Мухаммад

21

Перша частина питання:

Чому null вважається об’єктом у JavaScript?

Це помилка дизайну JavaScript, яку вони зараз не можуть виправити. Це повинен був бути тип null, а не type або взагалі не мати його. Це вимагає додаткової перевірки (іноді забутої) при виявленні реальних об'єктів і є джерелом помилок.

Друга частина питання:

Перевіряє


if (object == null)
Do something

те саме, що

if (!object)
Do something

Два чеки завжди обидва помилкові, за винятком:

  • об'єкт не визначений або нульовий: і те й інше.

  • об'єкт примітивний, а 0, ""або хибний: перший перевірити хибність, другий істинно.

Якщо об'єкт не є примітивним, а реальний об'єкт, як new Number(0), new String("")або new Boolean(false), то обидві перевірки є помилковими.

Отже, якщо "об'єкт" інтерпретується як "реальний об'єкт", то обидві перевірки завжди однакові. Якщо примітиви дозволені, то перевірки відрізняються за значеннями 0 "", та false.

У таких випадках, як object==nullнепомітні результати можуть бути джерелом помилок. Використання ==не рекомендується ніколи, ===а замість цього.

Третя частина питання:

А також:

Яка різниця між нульовим та невизначеним?

У JavaScript одна відмінність полягає в тому, що null має тип об'єкта, а undefined - тип undefined.

У JavaScript null==undefinedє істинним і вважається рівним, якщо тип ігнорується. Чому вони вирішили це, але 0 ""і false не рівні, я не знаю. Здається, це довільна думка.

У JavaScript null===undefinedне відповідає дійсності, оскільки тип повинен бути однаковим у ===.

Насправді нульові та невизначені тотожні, оскільки вони обидва представляють неіснування. Тож зробіть 0, і ""в цьому питанні теж, а може бути і порожні контейнери []і {}. Так багато типів того ж нічого не є рецептом помилок. Один тип або взагалі жоден не кращий. Я б намагався використовувати якомога менше.

'false', 'true' і '!' - це ще один мішок з глистами, який можна спростити, наприклад, if(!x)таif(x) лише вона є достатньою, вам не потрібні справжні та неправдиві.

Оголошений var xтип не визначений, якщо значення не задано, але воно повинно бути таким же, як якщо б x ніколи не було оголошено. Ще одне джерело помилок - порожній контейнер нічого. Тому найкраще декларувати та визначати це разом, як var x=1.

Люди кружляють по колах, намагаючись з'ясувати всі ці різні види нічого, але це все одне і те саме в складному різному одязі. Реальність така

undefined===undeclared===null===0===""===[]==={}===nothing

І, можливо, всі повинні кинути винятки.


8
Чудова відповідь, але це занадто далеко з []: " Насправді нульові та невизначені ідентичні ... і, можливо, порожні контейнери [] і {}. " Ви, напевно, могли б переконати мене в думці. {} Має бути деяким аромат нуля, але моє враження про те, що воно не повинно. Але менш суперечливо, порожній масив, []зрозуміло, має .push()функцію , тому немає жодного хорошого аргументу, щоб [] був нульовим. 0,02 дол.
ruffin

11
var x = null;

x визначається як null

y не визначено; // тому, що я цього не визначив

if (!x)

null оцінюється як хибний


8

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

Очікуйте нульове значення повернення в наступних ситуаціях:

  • Методи, що запитують DOM

    console.log(window.document.getElementById("nonExistentElement"));
    //Prints: null
  • Відповіді JSON, отримані на запит Ajax


    {
      name: "Bob",
      address: null
    }
  • RegEx.exec .

  • Нова функціональність, яка знаходиться в потоці. Наступні повертаються нульовими:


        var proto = Object.getPrototypeOf(Object.getPrototypeOf({}));

       // But this returns undefined:

        Object.getOwnPropertyDescriptor({}, "a");

Усі інші випадки відсутності позначаються невизначеними (як зазначає @Axel). Кожен із наступних відбитків "невизначений":

    var uninitalised;
    console.log(uninitalised);

    var obj = {};
    console.log(obj.nonExistent);

    function missingParam(missing){
        console.log(missing);
    }

    missingParam();

    var arr = [];
    console.log(arr.pop());        

Звичайно, якщо ви вирішили написати var unitialised = null; або повернути null з методу самостійно, тоді ви матимете null в інших ситуаціях. Але це має бути досить очевидним.

Третій випадок - це коли ви хочете отримати доступ до змінної, але навіть не знаєте, чи вона була оголошена. У цьому випадку використовуйте typeof, щоб уникнути помилки посилання:

if(typeof unknown !== "undefined"){
    //use unknown
}

Підсумково перевіряйте наявність нуля, коли ви маніпулюєте DOM, маючи справу з Ajax або використовуючи певні функції ECMAScript 5. Для всіх інших випадків безпечно перевірити, чи не визначено сувору рівність:

if(value === undefined){
  // stuff
}

8

Порівняння багатьох різних нульових перевірок у JavaScript:

http://jsfiddle.net/aaronhoffman/DdRHB/5/

// Variables to test
var myNull = null;
var myObject = {};
var myStringEmpty = "";
var myStringWhiteSpace = " ";
var myStringHello = "hello";
var myIntZero = 0;
var myIntOne = 1;
var myBoolTrue = true;
var myBoolFalse = false;
var myUndefined;

...trim...

http://aaron-hoffman.blogspot.com/2013/04/javascript-null-checking-undefined-and.html

Порівняльна діаграма Java Null Check


1
робить "var myUndefined;" визначити змінну (як відому змінну з невідомим типом)?
Фанат Ци

6

null та undefined - обидва помилкові для значення рівності (null == undefined): вони обоє згортаються до булевих false. Вони не є одним і тим же об'єктом (null! == undefined).

undefined - властивість глобального об'єкта ("вікно" у браузерах), але є примітивним типом, а не самим об'єктом. Це значення за замовчуванням для неініціалізованих змінних та функцій, що закінчуються без оператора return.

null - це примірник Object. null використовується для методів DOM, які повертають об'єкти колекції для вказівки порожнього результату, який надає помилкове значення без вказівки на помилку.


5

Деякі заходи:

null та undefined - це два різних значення. Один представляє відсутність значення для імені, а інший - відсутність імені.


Що відбувається в ifанкеті if( o ):

Вираження в круглих дужках о оцінюється, а потім ifнатискання клавіш у типовому примушуванні значення виразу в дужках - у нашому випадку o.

Значення Falsy (які будуть примусові до помилкових) у JavaScript мають значення: '', null, undefined, 0 і false .


5

Щоб додати відповідь на те, у чому різниця між undefinedтаnull , з JavaScript Definitive Guide 6th Edition, стор.41 на цій сторінці :

Ви можете розглянути undefinedможливість відображення системного, несподіваного або помилкового nullвідсутності значення та представити програмний рівень, нормальну чи очікувану відсутність значення. Якщо вам потрібно призначити одне з цих значень змінній чи властивості або передати одне з цих значень функції, nullмайже завжди це правильний вибір.


3

nullє об’єктом. Його тип недійсний. undefinedне є об’єктом; її тип не визначений.


11
неправильно - і те, nullі undefinedпервісні значення - typeof null === 'object'це мовна помилка, тому щоObject(null) !== null
Крістоф

Ні, ні. Об'єкт () передає роботу таким чином, див. Ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf - 15.2.2.1 новий об'єкт ([значення]) ... 8. (Значення аргументу не постачався або його тип був Null або Undefined.) Створіть новий власний об'єкт ECMAScript. Властивість [[прототипу]] щойно побудованого об'єкта встановлено на об’єкт прототипу Object. Властивість [[Class]] новоствореного об’єкта встановлено на "Object". Новостворений об’єкт не має властивості [[Значення]]. Поверніть новостворений нативний об’єкт.
kentaromiura

3
@Christoph: Я маю на увазі, ти маєш рацію. null має бути типом, я маю на увазі те, що ви не можете перевірити його таким чином, оскільки: alert (new Object ()! == new Object ()); / * вірно, новий екземпляр - це не той самий інстанцій / сповіщення (Object (null) .constructor == {} .constructor); / true, як у spec / alert (Object (null) .prototype == {} .prototype); / true, як у spec / alert (null instanceof Object); / Явно помилкова, означає нуль НЕ інстанціювати * / Але в основному є специфікація помилка XD см: uselesspickles.com/blog/2006/06/12 / ... і javascript.crockford.com/remedial.html
kentaromiura

2

Наступна функція показує, чому і здатна розробити різницю:

function test() {
        var myObj = {};
        console.log(myObj.myProperty);
        myObj.myProperty = null;
        console.log(myObj.myProperty);
}

Якщо ви телефонуєте

test();

Ви отримуєте

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

нуль

Перші console.log(...)спроби отримати myPropertyвід myObjпоки він ще не визначений - тому він отримує назад «невизначені». Після присвоєння йому null, другий console.log(...)повертається, очевидно, "null", оскільки myPropertyіснує, але має значенняnull присвоєне йому значення.

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


2

Наприклад window.someWeirdProperty, невизначений, так

"window.someWeirdProperty === null" оцінює помилковий час

"window.someWeirdProperty === undefined" оцінює до істинного.

Більш того, чекіф if (!o)- це не те саме, що перевірка if (o == null)на oнаявність false.


Чи можете ви уточнити різницю між двома умовами
rahul

прочитайте мою відповідь, він означає, що якщо o дорівнює 0, false або "" Булеве значення false: var undef, different = [0, "", null, false, undef]; for (var obj у різних) {alert (! obj); // 4 рази помилковий в IE, 5 у FF;)}
кентароміура

2

Інша прикольна річ про null, порівняно з невизначеною, - це те, що вона може збільшуватися.

x = undefined
x++
y = null
y++
console.log(x) // NaN
console.log(y) // 0

Це корисно для встановлення цифрових значень за замовчуванням для лічильників. Скільки разів ви встановили змінну до -1 у своїй декларації?


2

У Javascript null - це не objectтип, а primitaveтип.

Яка різниця? Невизначений посилається на покажчик, який не був встановлений. Null посилається на нульовий покажчик, наприклад, щось вручну встановило змінну для типуnull


2

Подивись на це:

   <script>
function f(a){
  alert(typeof(a));
  if (a==null) alert('null');
  a?alert(true):alert(false);
}
</script>
                                          //return:
<button onclick="f()">nothing</button>    //undefined    null    false
<button onclick="f(null)">null</button>   //object       null    false
<button onclick="f('')">empty</button>    //string               false
<button onclick="f(0)">zero</button>      //number               false
<button onclick="f(1)">int</button>       //number               true
<button onclick="f('x')">str</button>     //string               true

1

З "Принципи об'єктно-орієнтованого Javascript" Ніколаса Закаса

Але чому об’єкт, коли тип недійсний? (Насправді це було визнано помилкою TC39, комітетом, який розробляє та підтримує JavaScript. Ви можете пояснити, що null є порожнім вказівником об'єкта, що робить "об'єкт" логічним повернутим значенням, але це все ще заплутано.)

Закас, Микола К. (2014-02-07). Принципи об'єктно-орієнтованого JavaScript (Kindle Locations 226-227). Немає крохмальної преси. Kindle видання.

Це сказав:

var game = null; //typeof(game) is "object"

game.score = 100;//null is not an object, what the heck!?
game instanceof Object; //false, so it's not an instance but it's type is object
//let's make this primitive variable an object;
game = {}; 
typeof(game);//it is an object
game instanceof Object; //true, yay!!!
game.score = 100;

Невизначений випадок:

var score; //at this point 'score' is undefined
typeof(score); //'undefined'
var score.player = "felix"; //'undefined' is not an object
score instanceof Object; //false, oh I already knew that.

1

Найкращий спосіб подумати над «null» - згадати, як подібне поняття використовується в базах даних, де це вказує на те, що поле не містить «значення взагалі».

  • Так, значення товару відоме; це буде «безумовно». Він був инициализирован.
  • Значення елемента: "немає значення".

Це дуже корисна техніка для написання програм, які легше налагоджуються. Невизначена змінна може бути результатом помилки ... (як би ви знали?) ... але якщо змінна містить значення "null", ви знаєте, що "хтось десь у цій програмі встановив її на 'null.' "Тому я пропоную, коли вам потрібно позбутися значення змінної, не" delete "... встановіть її на" null. " Стара цінність осиротить і незабаром буде зібрана сміття; нове значення - "немає значення (зараз)". В обох випадках стан змінної є певним: "це, очевидно, свідомо, саме таким чином".


1
  1. Не визначено означає, що змінна була оголошена, але їй не було присвоєно жодного значення, тоді як Null може бути призначений змінній, що представляє "немає значення" (Null - оператор присвоєння)

2.Undefined - це сам тип, а Null - об’єкт.

3.Javascript може сам ініціалізувати будь-яку непризначену змінну до невизначеної, але вона ніколи не може встановлювати значення змінної до null. Це потрібно робити програмно.

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