Когда проверять неопределенность, а когда проверять ноль - PullRequest
20 голосов
/ 20 января 2011

[Bounty Edit]

Я ищу хорошее объяснение, когда вы должны установить / использовать null или undefined и где вам нужно это проверить.В основном, каковы общие практики для этих двух и действительно ли возможно рассматривать их отдельно в общем поддерживаемом коде?

Когда я могу безопасно проверить на === null, безопасно проверить на === undefined и когда мне нужно проверитьдля обоих с == null

Когда следует использовать ключевое слово undefined и когда следует использовать ключевое слово null

У меня есть различные проверки в формате

if (someObj == null) или if (someObj != null), которые проверяют как нулевые, так и неопределенные.Я хотел бы изменить все это на === undefined или === null, но я не уверен, как гарантировать, что это будет только один из двух, но не оба.

Где вы должны использовать чекидля null и где вы должны использовать чеки для undefined

Конкретный пример:

var List = []; // ordered list contains data at odd indexes.

var getObject = function(id) {
    for (var i = 0; i < List.length; i++) {
        if (List[i] == null) continue;
        if (id === List[i].getId()) {
            return List[i];
        }
    }
    return null;
}

var deleteObject = function(id) {
    var index = getIndex(id) // pretty obvouis function
    // List[index] = null; // should I set it to null?
    delete List[index]; // should I set it to undefined?
}

Это только один пример того, как я могу использовать оба null или undefined и я не знаю, какой из них правильный.

Есть ли случаи, когда вы должны проверить и null, и undefined, потому что у вас нет выбора?

Ответы [ 9 ]

11 голосов
/ 20 января 2011

Функции неявно возвращают undefined. Неопределенные ключи в массивах: undefined. Неопределенные атрибуты в объектах: undefined.

function foo () {

};

var bar = [];
var baz = {};

//foo() === undefined && bar[100] === undefined && baz.something === undefined

document.getElementById возвращает null, если элементы не найдены.

var el = document.getElementById("foo");

// el === null || el instanceof HTMLElement

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

Я рекомендую вам избегать null; используйте undefined.

5 голосов
/ 20 января 2011

Некоторые методы DOM возвращают null. Все свойства объекта, которые не были установлены, возвращают undefined при попытке доступа к ним, включая свойства Array. Функция без оператора return неявно возвращает undefined.

Я бы посоветовал вам точно знать, какие значения возможны для переменной или свойства, которые вы тестируете и тестируете эти значения явно и с уверенностью. Для тестирования null используйте foo === null. Для тестирования undefined я бы рекомендовал использовать typeof foo == "undefined" в большинстве ситуаций, поскольку undefined (в отличие от null) не является зарезервированным словом, а является простым свойством глобального объекта, который может быть изменен, а также по другим причинам, о которых я недавно писал здесь: переменная === undefined против переменной typeof === "undefined"

3 голосов
/ 20 января 2011

Разница между null и undefined заключается в том, что null само является значением и должно быть присвоено.Это не по умолчанию.Совершенно новая переменная без присвоенного ей значения: undefined.

var x;
// value undefined - NOT null.
x = null;
// value null - NOT undefined.
2 голосов
/ 02 февраля 2011

Мне кажется интересным отметить, что когда Windows была впервые написана, она не выполняла много проверок на наличие недействительных / NULL-указателей. В конце концов, ни один программист не будет настолько глуп, чтобы пропустить NULL там, где нужна правильная строка. А тестирование на NULL только делает код больше и медленнее.

В результате многие ОАЭ произошли из-за ошибок в клиентских программах, но все это досталось Microsoft. С тех пор Microsoft изменила Windows, чтобы в значительной степени проверять каждый аргумент на NULL.

Я думаю, что урок в том, что, если вы не уверены, что аргумент всегда будет действительным, вероятно, стоит проверить, что это так. Конечно, Windows используется многими программистами, в то время как ваша функция может использоваться только вами. Так что это, безусловно, влияет на вероятность неверного аргумента.

В таких языках, как C и C ++, вы можете использовать ASSERT, и я использую их ВСЕ время при использовании этих языков. Это заявления, которые проверяют определенные условия, которые вы никогда не ожидаете. Во время отладки вы можете проверить, что, на самом деле, они никогда не делают. Затем, когда вы делаете сборку релиза, эти операторы не включаются в скомпилированный код. В некотором смысле это кажется мне лучшим из обоих миров.

1 голос
/ 22 июля 2011

Если вы вызываете функцию без явного возврата, то она неявно возвращает undefined .Поэтому, если у меня есть функция, которая должна сказать, что она выполнила свою задачу, и ничего не получилось, например, XMLHTTPRequest, который ничего не возвращал, когда вы обычно ожидаете, что что-то произойдет (например, вызов базы данных), то я бы явно возвратил пустой .

0 голосов
/ 02 февраля 2011

Я бы отнесся к ним как к 2 совершенно разным значениям, и проверил бы, может ли произойти то, о котором вы знаете.

Если вы проверяете, было ли что-то еще присвоено значение, проверьте по undefined.

Если вы проверяете, является ли значение «ничто», проверьте «пустое»

Слегка надуманный пример:

Скажем, у вас есть серияAjax-запросы, и вы морально против использования обратных вызовов, поэтому у вас есть тайм-аут, который проверяет их завершение.

Ваша проверка будет выглядеть примерно так:

if (result !== undefined){
    //The ajax requests have completed
    doOnCompleteStuff();
    if (result !== null){
        //There is actually data to process
        doSomething(result);
    }
}

tldr;Это два разных значения, undefined означает, что значение не задано, null означает, что значение было задано, но значение равно 'none'.

0 голосов
/ 30 января 2011

Когда их устанавливать / использовать ...

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

Использовать ноль для преднамеренного или несоответствующего ответа.

Что касается того, как / когда проверять ...

undefined, null, 0, пустая строка, NaN и false будут FALSE посредством принуждения.Они известны как «ложные» значения ... все остальное верно.

Лучше всего - принуждение, а затем проверка на допустимые значения исключений ...


var something; //undefined

something = !!something; //something coerced into a boolean

//true if false, null, NaN or undefined
function isFalsish(value) {
  return (!value && value !== "" && value !== 0);
}

//get number or default
function getNumber(val, defaultVal) {
  defaultVal = isFalsish(defaultVal) ? 0 : defaultVal;
  return (isFalsish(val) || isNaN(val)) ? defaultVal : +val;
}

Числовое тестирование является реальнымbugger, поскольку true, false и null могут быть приведены к числу, а 0 - к false.

0 голосов
/ 29 января 2011

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

var List = []; // ordered list contains data at odd indexes.
var getObject = function(id) {
    for (var i = 1; i < List.length; i+=2) {
        if (id === List[i].getId()) {
            return List[i];
        }
    }
    // returns undefined by default
}

Ваш алгоритм имеет недостатки, потому что вы проверяете даже индексы (даже если вы знаете, что там ничего нет), и вы также неправильно используете null в качестве возвращаемого значения,

Эти функции действительно должны возвращать undefined, потому что это означает: таких данных нет

И вот вы в самом сердце проблемы.Если вы не до конца понимаете null и undefined и иногда можете использовать их неправильно, как вы можете быть настолько уверены, что другие будут использовать его правильно?Вы не можете.

Тогда есть Host objects с их отвратительным поведением, если вы спросите меня, вам лучше проверить оба.Это не повредит, на самом деле, это избавит вас от головной боли, связанной с кодом стороннего производителя или вышеупомянутыми non-native объектами.

За исключением этих двух случаев, в вашем собственном коде, вы можете сделать то, что сказал @bobince:

Сохранить undefined в качестве специального значения для сигнализации, когда другие языки могут выдавать исключение.

0 голосов
/ 20 января 2011

Undefined отличается от нуля при использовании! ==, но не при использовании более слабого! =, Потому что JavaScript в этом случае выполняет неявное приведение.

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

                            undefined   false
(SomeObject.foo)            false        false
(SomeObject.foo != null)    false        true
(SomeObject.foo !== null)   true         true
(SomeObject.foo != false)   true         false
(SomeObject.foo !== false)  true         false

Это взято из этого блога

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...