Подтвердить что ты не робот

Обработка различия между undefined - и нулевыми параметрами в JavaScript

Я очень хорошо знаю, что null и undefined отличаются от JavaScript. Однако я не могу решить, использовать ли этот факт или нет, когда мои собственные функции передаются одним из них в качестве аргумента.

Или, выраженный другим способом, должен myFoo(undefined) вернуть то же самое, что и myFoo(null)?

Или, в другом случае, поскольку myBar(1, 2, 3) (почти) то же самое, что и myBar(1, 2, 3, undefined, undefined), если myBar(1, 2, 3, null, null) возвращает то же самое, что и myBar(1, 2, 3)?

Я чувствую, что существует потенциал для путаницы в обоих случаях и что библиотека должна, вероятно, следовать соглашению при обработке null/ undefined.

Я не прошу личного мнения (поэтому, пожалуйста, выражайте их как комментарии, а не ответы). Я спрашиваю, знает ли кто-нибудь, есть ли лучшая практика, которой следует придерживаться, когда дело доходит до обработки этого различия. Ссылки на внешние источники приветствуются!

4b9b3361

Ответ 1

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

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

function asyncWorker(data, callback, timeout) {
    if (typeof callback === "undefined") {
        callback = function() { $("#log").append("<p>Done!</p>"); };
    }

    // ...

    if (callback) callback();
}

asyncWorker([1, 2, 3]); // default callback, no timeout
asyncWorker([4, 5, 6], null); // no callback, no timeout
asyncWorker([7, 8, 9], undefined, 10000); // default callback, 10s timeout

Конечно, вместо null можно использовать false или 0, но это может быть не так в более сложном примере. И зависит ли ваш код от дополнительной сложности параметров, полностью зависит от вас.: -)

Ответ 2

Лучшая практика для обработки аргументов

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

Шаг 2, 3 и 4 имеет для вас наибольшее значение

Как получить доступ к аргументам
Это то, что вам нужно будет выбрать на основе того, что делает этот метод, и вашей стратегии обработки переменного количества аргументов.

Возьмем это, например,

function foo() {
    var args = arguments.length == 1 ? 
        [document.body].concat([arguments[0]]) : 
        Array.prototype.slice.call(arguments);

    args[0].style.backgroundColor = args[1];
}

foo(document.body, "red");
foo("blue");​

Истинный логический или правдивый/фальшивый
Как проверить значения в значительной степени зависит от того, как настроен ваш код.

function foo(elem, color) {
    if (!color) { // the correct test here should be 'typeof color == "undefined"'
        color = "green";
    }
    elem.style.backgroundColor = color;
}

foo(document.body, "red"); //set the background color to red
foo(document.body); //set the background color to the default green
foo(document.body, "");​ //remove the background color !This will fail!

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

Когда дело доходит до обработки значений undefined, помните, что нет разницы в foo(undefined); и foo(); кроме, что длина коллекции arguments будет отличаться. Как это обрабатывается (и если это необходимо) зависит от того, как вы обращаетесь к аргументам.

Ответ 3

Это полностью зависит от вас, как вы обрабатываете аргументы, переданные вашей функции, так что это зависит от вас. Если вы хотите проверить, есть ли аргумент null, вы используете

if (myVar === null) { 

и если вы хотите проверить, есть ли аргумент undefined, вы используете

if (typeof myVar === "undefined") {

Если ожидаемый аргумент имеет значение, отличное от 0, null или undefined, вы можете проверить это, используя

if (myVar) { 

Итак, должен ли ваш myFoo(null) вести себя так же, как myFoo(undefined), полностью зависит от того, как вы справляетесь с этим внутри.

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