Могу ли я установить переменные в неопределенное или передать неопределенное в качестве аргумента?

304

Я немного запутался в JavaScript undefinedи nullценностях.

Что на if (!testvar)самом деле делает? Это проверяет undefinedи nullили просто undefined?

Как только переменная определена, могу ли я очистить ее undefined(следовательно, удалив переменную)?

Могу ли я передать undefinedв качестве параметра? Например:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");
AJ.
источник
Ответ

Ответы:

514

Я немного озадачен Javascript неопределенным и нулевым.

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

undefinedс другой стороны, это странная JavaScript-причуда. Это одноэлементный объект, который представляет внеполосные значения, по сути, второй аналогичный, но отличный null. Это подходит:

  1. Когда вы вызываете функцию с меньшим количеством аргументов, чем в списке аргументов в functionсписках операторов, непереданные аргументы устанавливаются в undefined. Вы можете проверить это, например:

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    С этим методом вы не можете определить разницу между dosomething(1)и dosomething(1, undefined); arg2будет одинаковое значение в обоих. Если вам нужно увидеть разницу, на которую вы можете посмотреть arguments.length, но такие необязательные аргументы обычно не очень читабельны.

  2. Когда функция не имеет return value;, она возвращается undefined. Обычно нет необходимости использовать такой результат возврата.

  3. Когда вы объявляете переменную, имея var aинструкцию в блоке, но еще не присвоили ей значение, это так undefined. Опять же, вам никогда не нужно полагаться на это.

  4. Оператор spooky typeofвозвращается, 'undefined'когда его операндом является простая переменная, которая не существует, вместо того, чтобы выдавать ошибку, как это обычно бывает, если вы пытаетесь обратиться к ней. (Вы также можете указать простую переменную, заключенную в скобки, но не полное выражение, включающее несуществующую переменную.) Для этого тоже не слишком много пользы.

  5. Это спорный. Когда вы получаете доступ к свойству объекта, который не существует, вы не сразу получаете ошибку, как в любом другом языке. Вместо этого вы получаете undefinedобъект. (И затем, когда вы попытаетесь использовать этот undefinedобъект позже в сценарии, он будет работать странным образом, и его будет гораздо сложнее отследить, чем если бы JavaScript только что выдал ошибку сразу.)

    Это часто используется для проверки существования свойств:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    Тем не менее, потому что вы можете назначить, undefinedкак и любое другое значение:

    o.prop= undefined;

    это фактически не обнаруживает, надежно ли там находится имущество. Лучше использовать inоператор, которого не было в исходной версии JavaScript Netscape, но который теперь доступен везде:

    if ('prop' in o)
        ...

Таким образом, undefinedэто специфический для JavaScript беспорядок, который смущает всех. Помимо необязательных аргументов функции, где у JS нет другого более элегантного механизма, undefinedследует избегать. Это никогда не должно было быть частью языка; nullсработало бы просто отлично для (2) и (3), а (4) является ошибкой, которая существует только потому, что в начале JavaScript не имел исключений.

что на if (!testvar)самом деле делает? Это тест для неопределенных и нулевых или просто неопределенных?

Такой «truthiness» тест проверяет против false, undefined, null, 0, NaNи пустые строки. Но в данном случае, да, это действительно undefinedсвязано с этим. ИМО, надо об этом более четко и сказать if (testvar!==undefined).

Как только переменная определена, я могу очистить ее обратно до неопределенной (следовательно, удалив переменную).

Вы, конечно, можете присвоить undefinedему, но это не удалит переменную. Только delete object.propertyоператор действительно удаляет вещи.

deleteдействительно предназначен для свойств, а не переменных как таковых. Браузеры позволят вам сойти с рук delete variable, но это не очень хорошая идея и не будет работать в строгом режиме ECMAScript Fifth Edition. Если вы хотите высвободить ссылку на что-либо, чтобы ее можно было собрать мусором, было бы более привычным сказать variable= null.

я могу передать неопределенный в качестве параметра?

Да.

bobince
источник
10
Какой фантастический ответ. Я только что провалил тест JavaScript: perfectionkills.com/javascript-quiz Позже я перечитал ваш ответ и попробуйте снова!
Скиллдрик
1
фиксированный, т.е (Я склонен не слишком беспокоиться о переназначении, поскольку сценарий может переопределить так много всего, что может испортить все, что невозможно решить в общем случае.)
bobince
2
@bobince undefinedодноэлементный объект? Что вы имеете в виду? Это примитивная ценность, а не объект.
Шиме Видас
2
@Hortitude: это точка (4). Я вообще не буду typeof foo=='undefined'; он имеет тенденцию использоваться для (4a) глобального сниффинга, и в этом случае я бы предпочел быть явным и сказать 'foo' in window, или (4b) для проверки самого undefined-value, и в этом случае я бы предпочел быть читаемым и сказать foo===undefined. В теории тестирование typeofпротив 'undefined'может иметь вариант использования, который не могут обеспечить другие конструкции: анализ наличия локальных переменных. Однако в действительности вы почти всегда знаете, какие переменные объявлены локальными.
Бобинц
4
Одно предупреждение с # 2, обычно функция без returnоператора возвращает undefined, но если функция является конструктором (вызывается с newоператором), она возвратит новый объект (значение thisвнутри конструктора), несмотря на отсутствие returnоператора. console.log((function (){}()));возвращается undefined. console.log((new function (){}()));возвращает объект.
бесполезный код
18

Вы не можете (не должны?) Определять что-либо как неопределенное, так как переменная больше не будет неопределенной - вы просто определили это для чего-то.

Вы не можете (не должны?) Переходить undefinedк функции. Если вы хотите передать пустое значение, используйте nullвместо этого.

Оператор if(!testvar)проверяет логические значения true / false, этот конкретный тест проверяет, является ли testvarзначение false. По определению, nullи undefinedне должны быть оценены ни как trueили false, но Равняется JavaScript , nullкак falseи выдает ошибку , если попытаться оценить неопределенную переменную.

Чтобы правильно проверить undefinedили nullиспользовать, используйте эти:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }
Тату Ульманен
источник
1
Тройное равенство также проверяет тип, поэтому приведение типов не выполняется. Дуглас Крокфорд не советует использовать операторы приведения типов ( ==и !=).
Skilldrick
3
Вы можете определить что-то как неопределенное. var a= undefined, Вы можете пройти fn(undefined). Если вы хотите найти разницу между неопределенным свойством pобъекта oи свойством p, которое определено и установлено на undefined, вы должны использовать 'p' in oоператор.
2010 года
1
Есть ли причина, почему не стоит проверять, testvar === undefinedа не более сложные typeof(testvar) === "undefined"?
2010 года
4
Есть еще одна веская причина для использования typeofтеста для неопределенных переменных: в отличие от этого null, undefinedэто просто свойство глобального объекта, которое само может быть переопределено. Он принимает только определенный стиль кодирования и пропущенный знак равенства и undefinedмолча изменяется:if (undefined = someVar) {...}
Тим Даун
1
@IanGrainger: ECMAScript 5 (реализован в текущих версиях всех браузеров) в основном исправляет это, делая undefinedнеизменное свойство глобального объекта, поэтому оно безопаснее, чем было раньше. Тем не менее, все еще возможно определить непостоянную переменную, вызываемую undefinedвнутри функции, поэтому проблема не исчезла полностью.
Тим Даун
13

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

Если бы только nullбыло доступно, вы бы не смогли определить, nullбыло ли оно преднамеренно установлено в качестве значения или значение еще не было установлено, если вы не использовали громоздкий перехват ошибок: например,

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

Тем не менее, если вы намеренно устанавливаете значение в null, строгое равенство с undefinedошибками, что позволяет вам различать nullи undefinedзначения:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

Посмотрите здесь ссылку, вместо того чтобы полагаться на то, что люди пренебрежительно говорят «мусор», например: «В общем, undefined - это беспорядок в JavaScript, который смущает всех». То, что вы растеряны, не означает, что это беспорядок.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Такое поведение также не относится к JavaScript и завершает обобщенное понятие , что логический результат может быть true, falseнеизвестный ( null), нет значения ( undefined), или что - то пошло не так ( error).

http://en.wikipedia.org/wiki/Undefined_value

Тодд
источник
И все nullравно сработало бы просто отлично. a == nullэто trueпотому , что типа Javascript принуждения.
sleepwalkerfx
11

Лучший способ проверить наличие нулевых значений:

if ( testVar !== null )
{
    // do action here
}

и для неопределенного

if ( testVar !== undefined )
{
    // do action here
}

Вы можете назначить переменную с неопределенным.

testVar = undefined;
//typeof(testVar) will be equal to undefined.
Рахул
источник
1
Лучший способ проверить наличие нулевых значений - использовать !==, а не!=
MBO
6

ДА, вы можете, потому что неопределенный определяется как неопределенный.

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

ваш случай:

test("value1", undefined, "value2")

Вы также можете создать свою собственную неопределенную переменную:

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

источник
5

Чтобы ответить на ваш первый вопрос, оператор not (( !) преобразует все, что ему дано, в логическое значение. Таким образом null, 0, false, NaNи ""(пустая строка) будет все , кажется ложной.

Skilldrick
источник
А также пустая строка и NaN (не число)
MBO
undefinedне будет отображаться как false, это вызовет ошибку «не определено».
Тату Ульманен
Тату Ульманен: не правда. if (undefined) {/* Do stuff*/}не выдаст ошибку, так undefinedкак существует как свойство глобального объекта. Что выдаст ошибку это что-то вродеif (someUndeclaredVariable) {/* Do stuff*/}
Тим Даун
2

JavaScript, как установить переменную неопределенной в командной строке:

Задайте для переменной значение undefined в jsтерминале командной строки javascript, который поставляется с Java в Ubuntu 12.10.

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

Если вы установите переменную в undefined в javascript:

Поместите это в myjs.html:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

Это печатает это:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

ПРЕДУПРЕЖДЕНИЕ! Когда вы устанавливаете переменную в неопределенное значение, вы устанавливаете переменную в другую переменную. Если работает какой-то подлый человек, undefined = 'rm -rf /';то всякий раз, когда вы устанавливаете переменную в значение undefined, вы получите это значение.

Вам может быть интересно, как я могу вывести инопланетян с неопределенным значением в начале и заставить их все еще работать. Это из-за подъема JavaScript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

Эрик Лещинский
источник
2

Попробуй это:

// found on UglifyJS
variable = void 0;
Cqq Cqq
источник
0

Для if (something)и if (!something)обычно используется для проверки, если что-то определено или не определено. Например:

if (document.getElementById)

Идентификатор преобразуется в логическое значение, поэтому undefinedинтерпретируется как false. Конечно, есть и другие значения (например, 0 и ''), которые также интерпретируются как false, но либо у идентификатора не должно быть разумного значения, либо вы довольны обработкой такого значения как неопределенного.

В Javascript есть deleteоператор, который можно использовать для удаления члена объекта. В зависимости от области действия переменной (т. Е. Глобальной или нет) вы можете удалить ее, чтобы сделать ее неопределенной.

Нет undefinedключевого слова, которое вы можете использовать как неопределенный литерал. Вы можете опустить параметры в вызове функции, чтобы сделать их неопределенными, но это можно использовать, только отправляя в функцию меньше параметров, вы не можете опустить параметр в середине.

Guffa
источник
0

Просто для забавы, вот довольно безопасный способ присвоения «неназначенной» переменной. Для того, чтобы это произошло, потребовалось бы, чтобы кто-то добавил к прототипу Object с тем же именем, что и случайно сгенерированная строка. Я уверен, что генератор случайных строк можно улучшить, но я просто взял один из этого вопроса: генерировать случайные строки / символы в JavaScript

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

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
rdans
источник